1.泛型和类型擦除
java语言的泛型,只存在程序源码中,在编译后的字节码文件中,就已经替换为原来的原生类型(Raw Type,也称为裸类型),并在相应的地方插入了强制转换类型。因此,对运行期的java语言来说,ArrayList 和ArrayList就是同一个类,java语言的泛型实现方法称之为类型擦除,基于这个方法实现的泛型称为伪泛型。
看个小demo,代码能运行吗?聪明的你肯定知道,这会报错。
public static String method(List<String> list){
System.out.println("string list");
return "";
}
public static Integer method(List<Integer> list){
System.out.println("integer list");
return 1;
}
public static void main(String[] args) {
method(new ArrayList<String>());
method(new ArrayList<Integer>());
}
正如你所想的那样。示例代码会提示入下图:
表明有多个相同的泛型擦除。
好,接下来,我们来做个试验:
我们将下面的代码的class文件利用反编译文件(如
JD-GUI–Mac下载方式brew cask install jd-gui)进行反编译看看结果:
public static void main(String[] args) {
List<Integer> list =new ArrayList<>();
list.add(1);
System.out.println(list.get(0));
结果:泛型被擦除了。看到没?
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(Integer.valueOf(1));
System.out.println(list.get(0));
}
2.自动装箱、拆箱与遍历循环
不多比比,先看demo
正常代码:
public static void main(String[] args) {
List<String> list =new ArrayList<>();
list.add("dfsaf");
List<Integer> listinz = new ArrayList<>();
listinz.add(1);
listinz.add(2);
for (Integer a :listinz){
System.out.println(a);
}
System.out.println(list.get(0));
}
反编译之后:
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("dfsaf");
ArrayList listinz = new ArrayList();
listinz.add(Integer.valueOf(1));
listinz.add(Integer.valueOf(2));
Iterator var3 = listinz.iterator();
while(var3.hasNext()) {
Integer a = (Integer)var3.next();
System.out.println(a);
}
System.out.println((String)list.get(0));
}
3条件编译
源代码:
public static void main(String[] args) {
if (true) {
System.out.println("true");
} else {
System.out.println(false);
}
}
反编译之后:
public static void main(String[] args) {
System.out.println("true");
}