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的泛型参数化类型已经被擦除掉了。

最新文章

  1. 修改mysql默认字符集的方案
  2. 过滤android应用列表(区分系统应用、第三方应用、sd卡中的应用)
  3. EasyUI 格式化DataGrid列
  4. mysql EF
  5. android中选择控件与选择界面自然过度效果的实现--一种新的交互设计
  6. [河南省ACM省赛-第三届] BUYING FEED (nyoj 248)
  7. react native 升级到0.31.0的相关问题 mac xcode开发环境
  8. 设为首页/加入收藏JS代码
  9. 如何在IIS上发布网站
  10. win10下安装ubuntu18.04
  11. 虚拟机ubuntu设置静态IP与主机、外网互ping配置流程
  12. 2019-3-22c# TextBox只允许输入数字,禁用右键粘贴,允许Ctrl+v粘贴数字
  13. Altium Desgner软件,PCB设计中铺铜的作用
  14. Android解析XML文件
  15. ASP_NET实现界面无刷新的DropdownList两级联动效果
  16. 类中的函数带有self,不带self的区别
  17. LINUX系统一一常用命令
  18. MergeSort 归并排序(java)
  19. oracle优化脚本
  20. 主机名/etc/hosts文件的作用

热门文章

  1. Debian Bug report logs - #724721 zsh: Tab completion error with vi
  2. 【php】面向对象(二)
  3. H5 环境检测
  4. Git应用详解第八讲:Git标签、别名与Git gc
  5. 让图片适合在静态文本控件窗口大小 MFC
  6. GeoGebra重复手段实现
  7. R语言kohonen包主要函数介绍
  8. ATcoder E - Flatten 质因子分解求LCM
  9. E1. Send Boxes to Alice (Easy Version)
  10. Python - 调用接口合并文件夹下多个Excel表