使用参数化类型来确定类型

时间:2013-09-04 09:26:19

标签: java generics

我正在浏览这个链接

Java Generic Class - Determine Type

我试过这个程序。

package my;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class GenericTypeIdentification {

    public static void main( String args[] ) {
        Node<Integer> obj = new GenericTypeIdentification().new SubNode<Integer>( 1 );
        ParameterizedType parameterizedType = ( ParameterizedType ) obj.getClass().getGenericSuperclass();
        Type clazz = parameterizedType.getActualTypeArguments()[0];
        if ( clazz == Integer.class ) {
            System.out.println( 1 );
        }
        else {
            System.out.println( 2 );
        }
    }

    class Node<T> {

        private final T value;

        public Node( T val ) {
            this.value = val;
        }

        public T evaluate() {
            return value;
        };

    }

    class SubNode<T> extends Node<T> {

        private final T value;

        public SubNode( T val ) {
            super( val );
            value = val;
        }

        @Override
        public T evaluate() {
            return value;
        };
    }
}

我的理解是它应该将输出打印为1,但它会打印2。请帮助我理解这一点。感谢。

2 个答案:

答案 0 :(得分:3)

google guiceTypeLiteral使用了实际有效的技巧。在泛型类的子类的构造函数中,即使在运行时, do 也可以访问父级的通用“实例化”...因为泛型类型信息已经存在在编译时保留用于继承。用法示例:

TypeLiteral<MyClass> test = new TypeLiteral<MyClass>() {}; // notice the {} to build an anon. subclass
System.err.println(test.getType()); // outputs "MyClass"

由于类型擦除,如果不使用泛型的子类,这不起作用;并且对于大多数应用来说可能有点过头了。

答案 1 :(得分:1)

在这种情况下,Clazz将是T.

泛型仅在java的编译时考虑。您可以通过查看其成员的类来尝试在运行时确定集合的类型参数的值(没有100%的确定性,您最终可以使用子类......)。无法在运行时确定空集合的类型参数值。