来自C ++,一些Java代码对我来说很奇怪。有人可以向我解释下面的代码片段应该做什么吗?
@SuppressWarnings("unchecked")
private static <T> Class<T> getGenericType(Class<?> clz) {
return (Class<T>) ((ParameterizedType) clz.getGenericSuperclass())
.getActualTypeArguments()[0];
}
我在回答另一个问题(see here)时看到了这一点,我想详细了解这个问题。
答案 0 :(得分:2)
假设您有一个通用类Foo
,如下所示:
public class Foo<T> {
T myVar;
}
在很多方面,这就像是C ++中的模板。 T
是某种类型,可以是String
,可以是Integer
,也可以是Object
,可以是SomeTypeYouveNeverHeardOf
,所有这些都取决于使用{Foo
的代码1}},而不是Foo
内的代码。
它的一个子类,Bar
:
public class Bar extends Foo<String> {}
Bar
不是泛型类,但它使用一个作为其超类。它指定,对于Bar
的所有实例,类型变量T
实际上是String
,因此它从myVar
继承的Foo
实例变量将始终为String
。
现在开始使用该设置,让我们转向您的方法。
首先,它以Class
个对象作为参数。我们假设我们将其称为Bar.class
。你的方法做的第一件事就是在它上面调用getGenericSuperclass()
,它会检索一个代表其超类的对象 - Foo<String>
。
现在,getGenericSuperclass()
被声明为返回一个Type
对象,但代码假设传入的类具有泛型继承(也就是说,它扩展了Foo<String>
之类的东西。而不只是Foo
),在这种情况下,它实际上将返回ParameterizedType
。所以它输入它并调用getActualTypeArguments()
来检索类型参数是什么 - String
的{{1}}部分。这是作为数组返回的,因为在更一般的情况下,它可以处理诸如extends Foo<String>
之类的东西。
获得了{1}个对象的1号数组,然后返回数组的第一个成员。在此示例中,返回的值为extends ComplexObject<String, Integer, Foo, Object>
。
答案 1 :(得分:1)
这个方法在我的系统上做了什么,现在我测试它,在运行时抛出一个异常。所以我猜它的作用是&#34;什么都没用。&#34;
public class GenericTest
{
public static void main( String[] args )
{
ArrayList<String> al = new ArrayList<>();
System.out.println( getGenericType( al.getClass() ) );
}
@SuppressWarnings( "unchecked" )
private static <T> Class<T> getGenericType( Class<?> clz )
{
return (Class<T>) ( (ParameterizedType) clz.getGenericSuperclass() )
.getActualTypeArguments()[0]; // line 28
}
}
run:
Exception in thread "main" java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class
at quicktest.GenericTest.getGenericType(GenericTest.java:28)
at quicktest.GenericTest.main(GenericTest.java:21)
C:\Users\Brenden\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 2 seconds)