Let's consider the following piece of code:
package index;
public class Main {
public static void main(String[] args) {
Inner inner = new Inner();
Type t = inner.getClass().getGenericSuperclass();
ParameterizedType p = (ParameterizedType) t;
Type[] a = p.getActualTypeArguments();
try {
Custom c = (Custom) ((Class) a[0]).newInstance();
c.f();
} catch (Exception e){}
}
private static abstract class AbstractClass<T> {
public abstract void doSth();
}
private static class Inner extends AbstractClass<Custom>{
public void doSth() {
}
}
private static class Custom{
public Custom(){
}
public void f(){
System.out.println("Custom");
}
}
}
And generated bytecode:
public class index/Main {
static synthetic INNERCLASS index/Main$1 null null
private static INNERCLASS index/Main$Custom index/Main Custom
private static INNERCLASS index/Main$Inner index/Main Inner
private static abstract INNERCLASS index/Main$AbstractClass index/Main AbstractClass
public <init>()V
L0
LINENUMBER 6 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
RETURN
L1
LOCALVARIABLE this Lindex/Main; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
public static main([Ljava/lang/String;)V
TRYCATCHBLOCK L0 L1 L2 java/lang/Exception
L3
LINENUMBER 8 L3
NEW index/Main$Inner
DUP
ACONST_NULL
INVOKESPECIAL index/Main$Inner.<init> (Lindex/Main$1;)V
ASTORE 1
L4
LINENUMBER 9 L4
ALOAD 1
INVOKEVIRTUAL java/lang/Object.getClass ()Ljava/lang/Class;
INVOKEVIRTUAL java/lang/Class.getGenericSuperclass ()Ljava/lang/reflect/Type;
ASTORE 2
L5
LINENUMBER 10 L5
ALOAD 2
CHECKCAST java/lang/reflect/ParameterizedType
ASTORE 3
L6
LINENUMBER 11 L6
ALOAD 3
INVOKEINTERFACE java/lang/reflect/ParameterizedType.getActualTypeArguments ()[Ljava/lang/reflect/Type;
ASTORE 4
L0
LINENUMBER 13 L0
ALOAD 4
ICONST_0
AALOAD
CHECKCAST java/lang/Class
INVOKEVIRTUAL java/lang/Class.newInstance ()Ljava/lang/Object;
CHECKCAST index/Main$Custom
ASTORE 5
L7
LINENUMBER 14 L7
ALOAD 5
INVOKEVIRTUAL index/Main$Custom.f ()V
L1
LINENUMBER 15 L1
GOTO L8
L2
ASTORE 5
L8
LINENUMBER 25 L8
RETURN
L9
LOCALVARIABLE c Lindex/Main$Custom; L7 L1 5
LOCALVARIABLE args [Ljava/lang/String; L3 L9 0
LOCALVARIABLE inner Lindex/Main$Inner; L4 L9 1
LOCALVARIABLE t Ljava/lang/reflect/Type; L5 L9 2
LOCALVARIABLE p Ljava/lang/reflect/ParameterizedType; L6 L9 3
LOCALVARIABLE a [Ljava/lang/reflect/Type; L0 L9 4
MAXSTACK = 3
MAXLOCALS = 6
}
-
It works and I cannot understand how does it works. It shows that it is possible to get information about superclasses parameters. I don't know how it is possible to get a such information because I looked at bytecode and there is no such information:
-
Is it ok to do it?
Aucun commentaire:
Enregistrer un commentaire