Java 语法糖 - 泛型擦除
Java About 3,854 words示例
Java 代码
public class Test {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(10);
Integer x = list.get(0);
}
}
字节码
Code:
中字节码都将泛型擦除了。
14: invokevirtual
:add
的是Object
类型。
23: checkcast
:在get
获取时会先校验转换。
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) 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: bipush 10
11: invokestatic #4 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
14: invokevirtual #5 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
17: pop
18: aload_1
19: iconst_0
20: invokevirtual #6 // Method java/util/ArrayList.get:(I)Ljava/lang/Object;
23: checkcast #7 // class java/lang/Integer
26: astore_2
27: return
LineNumberTable:
line 7: 0
line 8: 8
line 9: 18
line 10: 27
LocalVariableTable:
Start Length Slot Name Signature
0 28 0 args [Ljava/lang/String;
8 20 1 list Ljava/util/ArrayList;
27 1 2 x Ljava/lang/Integer;
LocalVariableTypeTable:
Start Length Slot Name Signature
8 20 1 list Ljava/util/ArrayList<Ljava/lang/Integer;>;
MethodParameters:
Name Flags
args
说明
在方法参数和返回值上的泛型不会被擦除。
Java 代码
public class Test2 {
public Set<Integer> test(List<String> list, Map<Integer, Object> map) {
return null;
}
}
字节码
可以看到方法体上有泛型类型。
Signature
也有泛型。
public java.util.Set<java.lang.Integer> test(java.util.List<java.lang.String>, java.util.Map<java.lang.Integer, java.lang.Object>);
descriptor: (Ljava/util/List;Ljava/util/Map;)Ljava/util/Set;
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=3, args_size=3
0: aconst_null
1: areturn
LineNumberTable:
line 14: 0
LocalVariableTable:
Start Length Slot Name Signature
0 2 0 this Lcom/example/dao/Test2;
0 2 1 list Ljava/util/List;
0 2 2 map Ljava/util/Map;
LocalVariableTypeTable:
Start Length Slot Name Signature
0 2 1 list Ljava/util/List<Ljava/lang/String;>;
0 2 2 map Ljava/util/Map<Ljava/lang/Integer;Ljava/lang/Object;>;
MethodParameters:
Name Flags
list
map
Signature: #42 // (Ljava/util/List<Ljava/lang/String;>;Ljava/util/Map<Ljava/lang/Integer;Ljava/lang/Object;>;)Ljava/util/Set<Ljava/lang/Integer;>;
可以通过反射获取这些未擦除的信息
public static void main(String[] args) throws NoSuchMethodException {
Method test = Test2.class.getMethod("test", List.class, Map.class);
Type[] types = test.getGenericParameterTypes();
for (Type type : types) {
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
System.out.println("原始类型#" + parameterizedType.getRawType());
Type[] arguments = parameterizedType.getActualTypeArguments();
for (int i = 0; i < arguments.length; i++) {
System.out.println("泛型参数#" + i + ", " + arguments[i]);
}
}
}
}
输出
原始类型#interface java.util.List
泛型参数#0, class java.lang.String
原始类型#interface java.util.Map
泛型参数#0, class java.lang.Integer
泛型参数#1, class java.lang.Object
Views: 1,774 · Posted: 2022-04-20
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...