创建TypeVariable实例

时间:2016-09-04 00:16:11

标签: java reflection type-variables

TypeVariable的{​​{3}}确实令人困惑,首先它指明了:

  

在反射方法第一次需要时创建一个类型变量

  

重复创建类型变量无效

所以我理解的是,TypeVariable只有一个实例在运行时代表一个类型变量,例如:

class A<T> {}

我们将在运行时有一个代表Type Variable的{​​{1}}实例。

但文档补充道:

  

可以在运行时实例化多个对象以表示给定的类型变量。尽管类型变量只创建一次,但这并不意味着需要缓存表示类型变量的实例。但是,表示类型变量的所有实例必须彼此相等()

从上面的引文中我了解到有两种实例化:

  1. 创建类型变量(我不明白)
  2. 实例化表示类型变量的多个实例
  3. 有人可以解释一下它们之间的区别吗?

2 个答案:

答案 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,即使它们代表相同的类型变量。

Ideone demo

答案 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) );
      }
}