Java泛型和编译优化的一个例子

发布时间:2019-11-20 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了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

这个逻辑很简单,就是简单的invokespecialArrayList<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,请注明来意。