2016-09-04 3 views
1

official documentation из TypeVariable действительно сбивает с толку, во-первых, он указывает, что:Создание TypeVariable экземпляров

Тип переменной создается в первый раз, она необходима отражающим методом

и

Повторное создание переменной типа не имеет эффекта

Так что я понимаю, что есть только один экземпляр TypeVariable, представляющий переменную типа во время выполнения, например:

class A<T> {} 

Мы будем иметь один экземпляр Type Variable, которые представляют T во время выполнения.

Но документация добавляет:

Несколько объектов могут быть созданы во время выполнения для представления данного переменного типа. Несмотря на то, что переменная типа создается только один раз, это не означает требования кэширования экземпляров, представляющих переменную типа. Тем не менее, все экземпляры, представляющие переменную типа должны быть равны() друг с другом

Из приведенных выше цитат, я понимаю, что есть два вида конкретизации:

  1. Создания переменного типа (который я дон «т понять)
  2. Instantiation нескольких экземпляров, представляющий тип переменной

Может кто-нибудь, пожалуйста, объясните, в чем разница между ними?

ответ

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

+0

Спасибо за ваше четкое объяснение, поэтому, когда третья цитата говорит 'Даже если переменная типа создается только один раз, она имеет то же значение, что и« Даже если экземпляр, представляющий переменную типа, создается только один раз »? – NinjaBoy2014

+0

«Даже если экземпляр, представляющий переменную типа, создается только один раз» неверен. «Даже если переменная типа создается только один раз« означает », хотя объявляется только одна переменная типа». –

+0

Значит, создание слова означает количество объявлений переменной типа, которые существуют в коде? – NinjaBoy2014

0

Глядя в исходный код TypeVariableImpl в пакете sun.reflect.generics.reflectiveObjects, равный метод определяется как:

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), а затем имя. Если оба они одинаковы, они равны.

Мое понимание: «Множество объектов may быть экземпляром во время выполнения для представления переменной данного типа». Он основан на реализации. Я бегу следующий код с 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)); 
     } 
}