获取祖先类的泛型类型的类



是否有一种简单的方法来获取祖先类的泛型参数?(不是这里讨论的直接父类:http://blog.xebia.com/2009/02/07/acessing-generic-types-at-runtime-in-java/,而是层次结构中的任何祖先类。

例如:假设我们有这些类:
class Class1<O,P,Q> {}
class Class2<R,S> extends Class1<R, String, S> {}
class Class3<U> extends Class2<List,U> {}
class Class4<W> extends Class2<W,Set> {}

给定一个特定的后代类(例如Class3Class4),我怎么能知道祖先类Class1的参数类型?请注意,所有这些信息都在编译时出现!

例如,我知道对于Class3<U>, Class1将被实例化为:<List, String, U>

同样,对于Class4<W>, Class1将被<W, String, Set>实例化。所以用反射应该是可以做到的。请注意,我对参数的运行时值不感兴趣,而只对编译时数据感兴趣。

谢谢你的帮助!

好吧,这里有一个方法…我并不是说这是最好的(甚至是好的)方法,我只是说你可以根据自己的需要调整它。

package forums;
import java.util.List;
import java.util.Set;
import java.lang.reflect.*;
class Class1<O,P,Q> {}
class Class2<R,S> extends Class1<R, String, S> {}
class Class3<U> extends Class2<List,U> {}
class Class4<W> extends Class2<W,Set> {}
public class GenericTypeHeirarchy
{
  public static void main(String[] args) {
    try {
      PrintGenericAncestorTypes(Class4.class, "    ");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  @SuppressWarnings("unchecked")
  public static void PrintGenericAncestorTypes(Class clazz, String pad) {
    Type supaType = clazz.getGenericSuperclass();
    ParameterizedType paramSupaType = null;
    if (supaType instanceof ParameterizedType)
      paramSupaType = (ParameterizedType) supaType;
    if (paramSupaType == null)
      return; // INVALID REQUEST! Parent isn't a generic type.
    Type[] supasArgTypes = paramSupaType.getActualTypeArguments();  //actually returns TypeVariableImpl[]
    for ( Type t : supasArgTypes ) {
      // Type subinterfaces: GenericArrayType, ParameterizedType, TypeVariable<D>, WildcardType
      if (t instanceof TypeVariable) {
        System.out.println( pad + clazz.getName() + ": <" + t + ">");
        PrintGenericAncestorTypes(clazz.getSuperclass(), pad + "    "); // <<<< RECURSION >>>>
      } else {
        System.out.println( pad + clazz.getName() + ": " + t);
      }
    }
  }
}

编辑:

这可能还不是你想要的…我认为这将是每个泛型参数类型的类(或类名)……但我也只能到这里了我不知道如何为一个类型获得一个类…Type接口是空的,因此必须将其强制转换为其他类型,以便从…当没有任何已知的类型子接口(GenericArrayType, ParameterizedType, TypeVariable或WildcardType)时,读取参数类型(如java.lang.String)。我假定TypeVariable<D>instanceOf TypeVariable

这是我的改进版本,但我不知道从哪里开始。

package forums;
import java.util.List;
import java.util.Set;
import java.lang.reflect.*;
class Class1<O,P,Q> {}
class Class2<R,S> extends Class1<R, String, S> {}
class Class3<U> extends Class2<List,U> {}
class Class4<W> extends Class2<W,Set> {}
public class GenericTypeHeirarchy
{
  public static void main(String[] args) {
    try {
      PrintGenericTypeTree(Class4.class);
      System.out.println("--------------------------n");
      PrintGenericTypeTree(Class3.class);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  //@SuppressWarnings("unchecked")
  public static void PrintGenericTypeTree(Class clazz) {
    if (clazz == null || clazz == java.lang.Object.class)
      return;
    //
    // class Class4<W> extends
    //
    System.out.print( "class " + clazz.getName() );
    TypeVariable[] argTypes = clazz.getTypeParameters();
    if (argTypes.length == 0)
      return;
    System.out.print( "<" );
    boolean first = true;
    for ( TypeVariable t : argTypes ) {
      System.out.print( (first?"":", ") + t.getName() );
      first = false;
    }
    System.out.print("> extends ");
    //
    // Class2<W,Set>
    //
    Class supaClass = clazz.getSuperclass();
    System.out.print(supaClass.getName());
    Type genericSupaType = clazz.getGenericSuperclass();
    ParameterizedType paramSupaType = null;
    if (genericSupaType instanceof ParameterizedType)
      paramSupaType = (ParameterizedType) genericSupaType;
    if (paramSupaType == null) { // Parent isn't a generic type.
      System.out.println();
      return; 
    }
    Type[] supasArgTypes = paramSupaType.getActualTypeArguments();  //actually returns TypeVariableImpl[]
    first = true;
    System.out.print( "<" );
    for ( Type t : supasArgTypes ) {
      System.out.print( (first?"":", ") + t );
      first = false;
    }
    System.out.println(">");
    PrintGenericTypeTree(supaClass);
  }
}

…下面是输出…

C:Javahomesrcforums>"C:Program FilesJavajdk1.6.0_16binjava.exe" -Xms4m -Xmx256m -enableassertions -cp c:javahomesrc;C:Javahomeclasses; forums.GenericTypeHeirarchy
class forums.Class4<W> extends forums.Class2<W, interface java.util.Set>
class forums.Class2<R, S> extends forums.Class1<R, class java.lang.String, S>
class forums.Class1<O, P, Q> extends java.lang.Object
--------------------------
class forums.Class3<U> extends forums.Class2<interface java.util.List, U>
class forums.Class2<R, S> extends forums.Class1<R, class java.lang.String, S>
class forums.Class1<O, P, Q> extends java.lang.Object

Ian Robertson想出了一个公平的解决方案。我记得它还不完整,但它应该很容易让你开始。

相关内容

  • 没有找到相关文章

最新更新