Java泛型和编译优化的一个例子
2024-10-09 02:21:43
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
的泛型参数化类型已经被擦除掉了。
最新文章
- 修改mysql默认字符集的方案
- 过滤android应用列表(区分系统应用、第三方应用、sd卡中的应用)
- EasyUI 格式化DataGrid列
- mysql EF
- android中选择控件与选择界面自然过度效果的实现--一种新的交互设计
- [河南省ACM省赛-第三届] BUYING FEED (nyoj 248)
- react native 升级到0.31.0的相关问题 mac xcode开发环境
- 设为首页/加入收藏JS代码
- 如何在IIS上发布网站
- win10下安装ubuntu18.04
- 虚拟机ubuntu设置静态IP与主机、外网互ping配置流程
- 2019-3-22c# TextBox只允许输入数字,禁用右键粘贴,允许Ctrl+v粘贴数字
- Altium Desgner软件,PCB设计中铺铜的作用
- Android解析XML文件
- ASP_NET实现界面无刷新的DropdownList两级联动效果
- 类中的函数带有self,不带self的区别
- LINUX系统一一常用命令
- MergeSort 归并排序(java)
- oracle优化脚本
- 主机名/etc/hosts文件的作用