脚本宝典收集整理的这篇文章主要介绍了Java泛型和编译优化的一个例子,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
public class Main { public static void main(String[] args) { ArrayList<String> strList = new ArrayList<String>(); Type type = ((ParameterizedType)strList.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; System.out.println(type); } }
public class Main { public static void main(String[] args) { ArrayList<String> strList = new ArrayList<String>(){}; Type type = ((ParameterizedType)strList.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; System.out.println(type); } }
这两个例子唯一的区别是后者的new ArrayList<String>(){}
初始化strList
的时候带了{}
执行了赋初值,虽然语法层面没有什么区别,但是在编译之后的结果却完全不一样。而且执行的结果也完全不一样,
前者执行结果:
E
后者执行结果:
class java.lang.String
前者的编译结果:
public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=3, args_size=1 0: new #2 // class java/util/ArrayList 3: dup 4: invokespecial #3 // Method java/util/ArrayList."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class; 12: invokevirtual #5 // Method java/lang/Class.getGenericSuperclass:()Ljava/lang/reflect/Type; 15: checkcast #6 // class java/lang/reflect/ParameterizedType 18: invokeinterface #7, 1 // InterfaceMethod java/lang/reflect/ParameterizedType.getActualTypeArguments:()[Ljava/lang/reflect/Type; 23: iconst_0 24: aaload 25: astore_2 26: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream; 29: aload_2 30: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 33: return
这个逻辑很简单,就是简单的invokespecial
了ArrayList
的<init>()
方法。
后者的编译结果:
public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=3, args_size=1 0: new #2 // class Main$1 3: dup 4: invokespecial #3 // Method Main$1."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class; 12: invokevirtual #5 // Method java/lang/Class.getGenericSuperclass:()Ljava/lang/reflect/Type; 15: checkcast #6 // class java/lang/reflect/ParameterizedType 18: invokeinterface #7, 1 // InterfaceMethod java/lang/reflect/ParameterizedType.getActualTypeArguments:()[Ljava/lang/reflect/Type; 23: iconst_0 24: aaload 25: astore_2 26: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream; 29: aload_2 30: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 33: return
这里就奇怪了,加了{}
之后竟然生成了内部类Main$1
:
final class Main$1 extends java.util.ArrayList<java.lang.String> ... { Main$1(); descriptor: ()V flags: Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/util/ArrayList."<init>":()V 4: return LineNumberTable: line 8: 0 } Signature: #9 // Ljava/util/ArrayList<Ljava/lang/String;>; ...
是java.util.ArrayList<java.lang.String>
的子类,这也就解释了后者的执行结果为何可以解析到strList
的泛型参数化类型是java.lang.String
了,因为它的实际类型在JVM执行的时候清楚地被标记成了内部类Main$1
这个java.util.ArrayList<java.lang.String>
的子类。而前者的strList
的泛型参数化类型已经被擦除掉了。
以上是脚本宝典为你收集整理的Java泛型和编译优化的一个例子全部内容,希望文章能够帮你解决Java泛型和编译优化的一个例子所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。