Java通用参数之间的区别

时间:2010-07-07 14:58:06

标签: java generics parameters

使用泛型参数传递泛型参数和使用泛型参数之间有什么区别?

示例:

简单通用类:

public class Foo<T> { /*...*/ }

将简单泛型类扩展为一些不相关类型的简单泛型类的简单类:

public class FooFoo extends Foo<Type1> { /*...*/ }

另一个通用类

public class Bar<T> extends FooFoo { /*...*/ }

我们的基类作为泛型参数需要扩展类Foo的东西

public class TestFooClass<T extends Foo<?>> { /*...*/ }

问题是这两个参数之间的差异

public class BarTestOne extends TestFooClass<Bar> { /*...*/ }

public class BarTestTwo extends TestFooClass<Bar<?>> { /*...*/ }

问题

Class<T> class = (Class<T>) ((Foo)getClass().getGenericSuperclass()).getActualTypeArguments()[0];

在第一种情况下代码工作在第二种情况下没有。

2 个答案:

答案 0 :(得分:3)

看起来您正在尝试确定TestFooClass参数化的实际类型?

在这种情况下,使用带有和不带泛型参数的泛型类的区别在于getActualTypeArguments()[0]将:

  1. 在第一种情况下,提供表示原始类型的类的实例
  2. 在第二种情况下提供ParameterizedType的实例(因此可能会得到ClassCastException)。如果在该ParameterizedType上调用getRawType(),则将获得表示原始类型的Class。
  3. 此:

    BarTestOne one = new BarTestOne();
    BarTestTwo two = new BarTestTwo();
    
    Class<?> clazz1 = (Class<?>) ((ParameterizedType) one.getClass().getGenericSuperclass()).getActualTypeArguments()[0];       
    Class<?> clazz2 = (Class<?>) ((ParameterizedType) ((ParameterizedType) two.getClass().getGenericSuperclass()).getActualTypeArguments()[0]).getRawType();
    
    System.out.println(clazz1.equals(clazz2));
    

    这将返回 true

    唉,任何更深层次的答案都超出了我对仿制药的了解。

答案 1 :(得分:0)

Bar表示Bar<Object>Bar<?>表示List。例如,如果你有List<?>,你可以添加它,如果你有getClass()你不能,因为编译器不知道你的对象是否与“实际通用”兼容输入“对象。”

至于反射代码,我不知道。它说this,取决于你所称的对象;在这种情况下,对象显然是{{1}} ...这个代码从哪里调用?