TypeVariable
的{{3}}确实令人困惑,首先它指明了:
在反射方法第一次需要时创建一个类型变量
和
重复创建类型变量无效
所以我理解的是,TypeVariable
只有一个实例在运行时代表一个类型变量,例如:
class A<T> {}
我们将在运行时有一个代表Type Variable
的{{1}}实例。
但文档补充道:
可以在运行时实例化多个对象以表示给定的类型变量。尽管类型变量只创建一次,但这并不意味着需要缓存表示类型变量的实例。但是,表示类型变量的所有实例必须彼此相等()
从上面的引文中我了解到有两种实例化:
有人可以解释一下它们之间的区别吗?
答案 0 :(得分:0)
考虑以下课程:
class Ideone<T> {
List<T> getList() { ... }
}
可以说代表类<T>
的类型变量和方法上的<T>
不一定是同一个实例:
TypeVariable onClass = Ideone.class.getTypeParameters()[0];
TypeVariable onMethod = Ideone.class.getDeclaredMethod("getList").getReturnType().getTypeParameters()[0];
System.out.println(onClass == onMethod);
打印false
,即使它们代表相同的类型变量。
答案 1 :(得分:0)
通过在sun.reflect.generics.reflectiveObjects包中查看TypeVariableImpl的源代码,equal方法定义为:
158 public boolean equals(Object o) {
159 if (o instanceof TypeVariable) {
160 TypeVariable that = (TypeVariable) o;
161
162 GenericDeclaration thatDecl = that.getGenericDeclaration();
163 String thatName = that.getName();
164
165 return
166 (genericDeclaration == null ?
167 thatDecl == null :
168 genericDeclaration.equals(thatDecl)) &&
169 (name == null ?
170 thatName == null :
171 name.equals(thatName));
172
173 } else
174 return false;
175 }
因此,首先查看声明,意味着从哪里获得此TypeVariable实例(获取TypeVariable实例的类),然后是名称。如果两者相同,则相同。
我的理解是&#34;多个对象可以在运行时实例化以表示给定的类型变量。&#34;它基于实施。我使用jdk1.7运行以下代码,结果显示该方法的返回类型中的TypeVariable实例是从类声明获得的相同实例:
public class TestMain
{
public interface MyInterfaceC<A,B,c> {
}
public class Test<A,B> implements MyInterfaceC<A,B,Integer> {
public MyInterfaceC<A,B,Integer> returnThis() {
return null;
}
}
public static void main(String args[]) throws Exception {
Type[] ts = Test.class.getGenericInterfaces();
TypeVariable t1 = (TypeVariable)(((ParameterizedType)ts[0]).getActualTypeArguments()[0]);
TypeVariable[] cmp = MyInterfaceC.class.getTypeParameters();
Type mtdRet = Test.class.getDeclaredMethod( "returnThis" ).getGenericReturnType();
Type[] mtdRaw = ((ParameterizedType)mtdRet).getActualTypeArguments();
TypeVariable mtd = (TypeVariable)mtdRaw[0];
System.out.println( "cmp[0].equal(mtd)?" + cmp[0].equals( mtd ) + ", cmp[0]==mtd? " + (cmp[0]==mtd) );
System.out.println( "mtd.equal(t1)?" + mtd.equals( t1 ) + ", mtd==t1? " + (mtd==t1) );
}
}