Get “real” class of generic type

前端 未结 5 637
傲寒
傲寒 2021-02-02 16:33

How can I get the \"real\" class of a generic type?

For Example:

public class MyClass {
    public void method(){
        //something

        S         


        
相关标签:
5条回答
  • 2021-02-02 17:18

    Note that approaches relying on 'getClass()' on an instance received with a generic type will get the actual type of that object, which is not necessarily the generic type - which would be the type by which the caller knew the instance.

    For example, consider the case where the caller handles an object by an interface; when passing to generic constructs, the generic type will be the interface, not the instance's actual class.

    Consider the following example "Pair" class, which allows two object references to be returned through a POJO:

    public class Pair<U,V>
    {
        public final U first;
        public final V second;
        public static <U,V> Pair<U,V> of (U first, V second)
        {
            return new Pair<U,V> (first, second);
        }
        protected Pair (U first, V second)
        {
            this.first  = first;
            this.second = second;
        }
    }
    

    We were considering how to modify the 'Pair.of()' factory function to return a Comparable Pair derived class, if U and V were both Comparable. However, while we can tell whether 'first' and 'second' are comparable using instanceof, we don't know that 'U' and 'V' are themselves comparable.

    For this to work, the exact type of Pair returned by Pair.of() must depend on the generic types, not the actual argument types.

    0 讨论(0)
  • 2021-02-02 17:28

    In the case of your situation, you can't. However, you might be able to use Super Type Tokens for this type of thing: http://gafter.blogspot.com/2006/12/super-type-tokens.html

    An example implementation of these is the TypeReference class of the Jackson json processing library.

    This is advanced stuff and probably more than you wanted to know ;-)

    0 讨论(0)
  • 2021-02-02 17:29

    As others have explained, you cannot do it in that fashion but this is how it's usually achieved in java.

    public class MyClass<T> {
        public void method(Class<T> clazz) {
            // something
    
            System.out.println(clazz.getName());
    
            // something
        }
    }
    

    and you use it like this

    new MyClass<String>().method(String.class);
    
    0 讨论(0)
  • If you have a instance variable of type T in your class, and it happens to be set, then you could print the class of that variable.

    public class Test<T> {
    
        T var;
    
        public static void main(String[] args) {
            Test<Integer> a = new Test<Integer>();
            System.out.println(a.boo());
            a.setVar(new Integer(10));
            System.out.println(a.boo());
        }
    
        public String boo() {
            if (var == null) {
                return "Don't know yet";
            }
            return var.getClass().getSimpleName();
        }
    
        public void setVar(T var) {
            this.var = var;
        }
    
        public T getVar() {
            return var;
        }
    }
    
    0 讨论(0)
  • 2021-02-02 17:34

    You can't. The information is stripped from the code at compile time, a process that is known as type erasure. For more, please look here: Type Erasure

    edit: sorry my bad, the information is not loaded at run time.

    0 讨论(0)
提交回复
热议问题