दिलचस्प पोस्ट
एल्गोरिदम बताने के लिए कि दो सरणी के समान सदस्य हैं या नहीं यूनिकोडडेकोड एर्रर: 'एएससीआई' कोडेक स्थिति 1 में बाइट 0x एफ डीकोड नहीं कर सकता लक्ष्य बनाने के लिए आप मेसेफाइल को कैसे बल देते हैं System.IO.FileSystemWatcher एक नेटवर्क-सर्वर फ़ोल्डर की निगरानी – प्रदर्शन विचार एएसपी.नेट एमवीसी में क्रिस्टल रिपोर्ट्स सी में सरणी तत्वों को एक्सेस करने का एक अलग तरीका java Runtime.getRunTime ()। exec और वाइल्डकार्ड? आप form1 से form2 और form1 पर वापस ऑब्जेक्ट कैसे पास करते हैं? अपने नाम के आधार पर तरीके को गतिशील कैसे कॉल करें? एक नकली / स्टब पायथन मॉड्यूल जैसे urllib कैसे हो सकता है जावास्क्रिप्ट में ऑब्जेक्ट हटाना कैसे अजगर में टो पहचान को बदलने के लिए? मानक पुस्तकालय प्रकार और उपयोगकर्ता परिभाषित प्रकार एकाधिक क्षेत्रों के साथ संग्रह GetValue (उपवर्ग। वर्ग) का उपयोग कर फायरबसे में उपवर्ग को कैसे हटाना है

रनटाइम पर सामान्य प्रकार का वर्ग प्राप्त करें

इसे कैसे प्राप्त किया जा सकता है?

public class GenericClass<T> { public Type getMyType() { //How do I return the type of T? } } 

मैंने जिस चीज की कोशिश की है, वह सब कुछ हमेशा उपयोग किए जाने वाले विशिष्ट प्रकार की बजाय Object देता है

Solutions Collecting From Web of "रनटाइम पर सामान्य प्रकार का वर्ग प्राप्त करें"

जैसा कि अन्य लोगों का उल्लेख है, कुछ परिस्थितियों में प्रतिबिंब के माध्यम से यह केवल संभव है

यदि आपको वास्तव में प्रकार की आवश्यकता है, तो यह सामान्य (टाइप-सुरक्षित) वैकल्पिक हल पैटर्न है:

 public class GenericClass<T> { private final Class<T> type; public GenericClass(Class<T> type) { this.type = type; } public Class<T> getMyType() { return this.type; } } 

मैंने ऐसा कुछ देखा है

 private Class<T> persistentClass; public Constructor() { this.persistentClass = (Class<T>) ((ParameterizedType) getClass() .getGenericSuperclass()).getActualTypeArguments()[0]; } 

हाइबरनेट GenericDataAccessObjects उदाहरण में

जेनरिक्स को रन-टाइम पर रीफ़ाईड नहीं किया जाता है इसका मतलब है कि रन-टाइम में सूचना मौजूद नहीं है

पिछड़े संगतता को संगत करते हुए जावा में जेनेरिक को जोड़ना एक दौरे-डी-बल था (आप इसके बारे में मूल पत्र देख सकते हैं: भविष्य के लिए सुरक्षित बनाना: जावा प्रोग्रामिंग भाषा में सामान्यता जोड़ने के लिए )।

इस विषय पर एक समृद्ध साहित्य है, और कुछ लोग वर्तमान स्थिति से असंतुष्ट हैं, कुछ कहते हैं कि वास्तव में यह एक आकर्षण है और इसके लिए कोई वास्तविक आवश्यकता नहीं है। आप दोनों लिंक पढ़ सकते हैं, मैंने उन्हें काफी दिलचस्प पाया

जरूर आप कर सकते हो।

पिछली संगतता कारणों के लिए जावा रनटाइम पर जानकारी का उपयोग नहीं करता है। लेकिन जानकारी वास्तव में मेटाडेटा के रूप में मौजूद है और प्रतिबिंब के माध्यम से पहुँचा जा सकता है (लेकिन यह अभी भी टाइप-चेकिंग के लिए उपयोग नहीं किया गया है)।

आधिकारिक एपीआई से:

http://download.oracle.com/javase/6/docs/api/java/lang/reflect/ParameterizedType.html#getActualTypeArguments%28%29

हालांकि , आपके परिदृश्य के लिए मैं प्रतिबिंब का उपयोग नहीं करेगा मैं व्यक्तिगत रूप से अधिक रूपरेखा कोड के लिए उपयोग करने के लिए इच्छुक हूँ आपके मामले में मैं सिर्फ एक कंस्ट्रक्टर परम के रूप में टाइप जोड़ूंगा।

अमरूद का उपयोग करें

 import com.google.common.reflect.TypeToken; import java.lang.reflect.Type; public class GenericClass<T> { private final TypeToken<T> typeToken = new TypeToken<T>(getClass()) { }; private final Type type = typeToken.getType(); // or getRawType() to return Class<? super T> public Type getType() { return type; } public static void main(String[] args) { GenericClass<String> example = new GenericClass<String>() { }; System.out.println(example.getType()); // => class java.lang.String } } 

थोड़ी देर पहले, मैंने कुछ पूर्ण-पूर्ण उदाहरणों को यहां पोस्ट किया, जिनमें अमूर्त वर्ग और उप-वर्ग शामिल हैं

नोट: इसके लिए जरूरी है कि आप GenericClass क्लास के उपवर्ग को GenericClass ताकि वह सही प्रकार के प्रकार पैरामीटर को बाँध सकें। अन्यथा यह सिर्फ T रूप में टाइप करेगा।

जावा जेनेरिक ज्यादातर समय संकलित करते हैं, इसका मतलब यह है कि टाइपटाइम रनटाइम पर खो जाता है।

 class GenericCls<T> { T t; } 

जैसे कुछ करने के लिए संकलित किया जाएगा

 class GenericCls { Object o; } 

रनटाइम पर टाइप की जानकारी पाने के लिए आपको इसे सीटीओआर के तर्क के रूप में जोड़ना होगा।

 class GenericCls<T> { private Class<T> type; public GenericCls(Class<T> cls) { type= cls; } Class<T> getType(){return type;} } 

उदाहरण:

 GenericCls<?> instance = new GenericCls<String>(String.class); assert instance.getType() == String.class; 

इयान रॉबर्टसन द्वारा इस आलेख में वर्णित तकनीक मेरे लिए काम करती है

संक्षिप्त त्वरित और गंदे उदाहरण में:

  public abstract class AbstractDAO<T extends EntityInterface, U extends QueryCriteria, V> { /** * Method returns class implementing EntityInterface which was used in class * extending AbstractDAO * * @return Class<T extends EntityInterface> */ public Class<T> returnedClass() { return (Class<T>) getTypeArguments(AbstractDAO.class, getClass()).get(0); } /** * Get the underlying class for a type, or null if the type is a variable * type. * * @param type the type * @return the underlying class */ public static Class<?> getClass(Type type) { if (type instanceof Class) { return (Class) type; } else if (type instanceof ParameterizedType) { return getClass(((ParameterizedType) type).getRawType()); } else if (type instanceof GenericArrayType) { Type componentType = ((GenericArrayType) type).getGenericComponentType(); Class<?> componentClass = getClass(componentType); if (componentClass != null) { return Array.newInstance(componentClass, 0).getClass(); } else { return null; } } else { return null; } } /** * Get the actual type arguments a child class has used to extend a generic * base class. * * @param baseClass the base class * @param childClass the child class * @return a list of the raw classes for the actual type arguments. */ public static <T> List<Class<?>> getTypeArguments( Class<T> baseClass, Class<? extends T> childClass) { Map<Type, Type> resolvedTypes = new HashMap<Type, Type>(); Type type = childClass; // start walking up the inheritance hierarchy until we hit baseClass while (!getClass(type).equals(baseClass)) { if (type instanceof Class) { // there is no useful information for us in raw types, so just keep going. type = ((Class) type).getGenericSuperclass(); } else { ParameterizedType parameterizedType = (ParameterizedType) type; Class<?> rawType = (Class) parameterizedType.getRawType(); Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); TypeVariable<?>[] typeParameters = rawType.getTypeParameters(); for (int i = 0; i < actualTypeArguments.length; i++) { resolvedTypes.put(typeParameters[i], actualTypeArguments[i]); } if (!rawType.equals(baseClass)) { type = rawType.getGenericSuperclass(); } } } // finally, for each actual type argument provided to baseClass, determine (if possible) // the raw class for that type argument. Type[] actualTypeArguments; if (type instanceof Class) { actualTypeArguments = ((Class) type).getTypeParameters(); } else { actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments(); } List<Class<?>> typeArgumentsAsClasses = new ArrayList<Class<?>>(); // resolve types by chasing down type variables. for (Type baseType : actualTypeArguments) { while (resolvedTypes.containsKey(baseType)) { baseType = resolvedTypes.get(baseType); } typeArgumentsAsClasses.add(getClass(baseType)); } return typeArgumentsAsClasses; } } 

मुझे नहीं लगता है कि आप कर सकते हैं, जावा का उपयोग करता है जब एपायर का उपयोग करता है तो संकलन करता है ताकि आपका कोड अनुप्रयोगों और पुस्तकालयों के साथ संगत हो जो प्री-जेनरिक्स बनाए गए थे।

ओरैकल डॉक्स से:

प्रकार मिटा देना

जेनरिक्स को जावा भाषा में पेश किया गया था ताकि समय को संकलित करने के लिए सख्त प्रकार की जांच हो सके और जेनेरिक प्रोग्रामिंग का समर्थन किया जा सके। जेनेरिक को कार्यान्वित करने के लिए, जावा कम्पाइलर इस प्रकार के एरर को लागू करता है:

सभी प्रकार के मापदंडों को अपनी सीमा या वस्तु के साथ सामान्य प्रकारों में बदल दें यदि प्रकार पैरामीटर असीम हैं। उत्पादित बाइटकोड, इसलिए, केवल साधारण वर्ग, इंटरफेस, और तरीके शामिल हैं। टाइप सुरक्षा को सुरक्षित रखने के लिए जरूरी प्रकार डालें। विस्तारित सामान्य प्रकारों में बहुरूपता को संरक्षित करने के लिए पुल के तरीकों को उत्पन्न करें। प्रकार मिटाने सुनिश्चित करता है कि पैरामीटर वाले प्रकारों के लिए कोई नई कक्षा नहीं बनाई जाती है; फलस्वरूप, जेनेरिक में कोई रनटाइम ओवरहेड नहीं होता है

http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

मैंने दृष्टिकोण का पालन किया:

 public class A<T> { protected Class<T> clazz; public A() { this.clazz = (Class<>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } public Class<T> getClazz() { return clazz; } } public class B extends A<C> { /* ... */ public void anything() { // here I may use getClazz(); } } 

यह मेरा समाधान है:

 import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; public class GenericClass<T extends String> { public static void main(String[] args) { for (TypeVariable typeParam : GenericClass.class.getTypeParameters()) { System.out.println(typeParam.getName()); for (Type bound : typeParam.getBounds()) { System.out.println(bound); } } } } 

यहाँ समाधान काम कर रहा है !!!

 @SuppressWarnings("unchecked") private Class<T> getGenericTypeClass() {    try {        String className = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0].getTypeName();        Class<?> clazz = Class.forName(className);        return (Class<T>) clazz;    } catch (Exception e) {        throw new IllegalStateException("Class is not parametrized with generic type!!! Please use extends <> ");    } } 

नोट: सुपरक्लास के रूप में ही इस्तेमाल किया जा सकता है
1. टाइप क्लास के साथ विस्तारित किया जाना है ( Child extends Generic<Integer> )
या
2. को अनाम क्रियान्वयन के रूप में बनाया जाना है ( new Generic<Integer>() {}; )

मुझे लगता है कि एक और शानदार समाधान है

आप क्या करना चाहते हैं (सुरक्षित रूप से) concerete वर्ग से सुपरक्लास तक सामान्य प्रकार पैरामीटर के प्रकार "पास"

यदि आप क्लास पर "मेटाडेटा" के रूप में क्लास प्रकार के बारे में सोचने की अनुमति देते हैं, तो यह रनटाइम पर एन्कोडिंग मेटाडेटा के लिए जावा विधि का सुझाव देता है: एनोटेशन

सबसे पहले इन पंक्तियों के साथ एक कस्टम एनोटेशन परिभाषित करें:

 import java.lang.annotation.*; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface EntityAnnotation { Class entityClass(); } 

इसके बाद आपको अपने उपवर्ग को एनोटेशन जोड़ना होगा।

 @EntityAnnotation(entityClass = PassedGenericType.class) public class Subclass<PassedGenericType> {...} 

फिर आप अपने बेस क्लास में कक्षा प्रकार प्राप्त करने के लिए इस कोड का उपयोग कर सकते हैं:

 import org.springframework.core.annotation.AnnotationUtils; . . . private Class getGenericParameterType() { final Class aClass = this.getClass(); EntityAnnotation ne = AnnotationUtils.findAnnotation(aClass, EntityAnnotation.class); return ne.entityClass(); } 

इस दृष्टिकोण की कुछ सीमाएं हैं:

  1. आप जेनेरिक प्रकार ( PassedGenericType ) को दो जगहों में निर्दिष्ट करते हैं, जो कि गैर-सूखा है
  2. यह केवल तभी संभव है यदि आप कंक्रीट उप-वर्गों को संशोधित कर सकते हैं।
 public abstract class AbstractDao<T> <br> { private final Class<T> persistentClass; public AbstractDao() { this.persistentClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()) .getActualTypeArguments()[0]; } } 

आप नहीं कर सकते यदि आप क्लास में टाइप T के एक सदस्य के चर को जोड़ते हैं (आप भी इसे आरंभ करने की आवश्यकता नहीं है), तो आप उस प्रकार का पुनर्प्राप्त करने के लिए इसका इस्तेमाल कर सकते हैं

सिर्फ मामले में आप जेनेरिक प्रकार का उपयोग कर एक चर का उपयोग कर सकते हैं, तो आप आसानी से इस समस्या को हल कर सकते हैं जैसे कि एक getClassType विधि निम्नानुसार है:

 public class Constant<T> { private T value; @SuppressWarnings("unchecked") public Class<T> getClassType () { return ((Class<T>) value.getClass()); } } 

मैं प्रदान किए गए वर्ग ऑब्जेक्ट का उपयोग बाद में जांचने के लिए करता हूं कि क्या यह किसी दिए गए वर्ग का उदाहरण है, निम्नानुसार है:

 Constant<?> constant = ...; if (constant.getClassType().equals(Integer.class)) { Constant<Integer> integerConstant = (Constant<Integer>)constant; Integer value = integerConstant.getValue(); // ... } 

यहां मेरी चाल है:

 public class Main { public static void main(String[] args) throws Exception { System.out.println(Main.<String> getClazz()); } static <T> Class getClazz(T... param) { return param.getClass().getComponentType(); } } 

यहां कुछ उत्तर पूरा करने के लिए, मुझे माईजनरिक क्लास के पैरामीट्रिड टाइप प्राप्त करना पड़ा, भले ही पुनरीक्षण की सहायता से, पदानुक्रम कितना बड़ा हो,

 private Class<T> getGenericTypeClass() { return (Class<T>) (getParametrizedType(getClass())).getActualTypeArguments()[0]; } private static ParameterizedType getParametrizedType(Class clazz){ if(clazz.getSuperclass().equals(MyGenericClass.class)){ // check that we are at the top of the hierarchy return (ParameterizedType) clazz.getGenericSuperclass(); } else { return getParametrizedType(clazz.getSuperclass()); } } 

यहाँ मेरा समाधान है

 public class GenericClass<T> { private Class<T> realType; public GenericClass() { findTypeArguments(getClass()); } private void findTypeArguments(Type t) { if (t instanceof ParameterizedType) { Type[] typeArgs = ((ParameterizedType) t).getActualTypeArguments(); realType = (Class<T>) typeArgs[0]; } else { Class c = (Class) t; findTypeArguments(c.getGenericSuperclass()); } } public Type getMyType() { // How do I return the type of T? (your question) return realType; } } 

चाहे कितने स्तर आपकी कक्षा के पदानुक्रम में हो, यह समाधान अभी भी काम करता है, उदाहरण के लिए:

 public class FirstLevelChild<T> extends GenericClass<T> { } public class SecondLevelChild extends FirstLevelChild<String> { } 

इस मामले में, GetMyType () = java.lang.String

यहाँ एक तरीका है, जिसका मुझे एक या दो बार उपयोग करना पड़ा है:

 public abstract class GenericClass<T>{ public abstract Class<T> getMyType(); } 

साथ में

 public class SpecificClass extends GenericClass<String>{ @Override public Class<String> getMyType(){ return String.class; } } 

मुझे यह समझना आसान और आसानी से समझाने योग्य समाधान है

 public class GenericClass<T> { private Class classForT(T...t) { return t.getClass().getComponentType(); } public static void main(String[] args) { GenericClass<String> g = new GenericClass<String>(); System.out.println(g.classForT()); System.out.println(String.class); } }