您的位置 首页 java

Java泛型擦除

在我们讲述 时,其中涉及到了一个解语法糖。

语法糖只不过是一种程序的表达式,语法糖可以提高程序的可读性,语法糖经过编译后,将会恢复原来的样貌。

  • 泛型和类型擦除
  • foreach语法

1. 泛型和类型擦除

泛型的本质是参数化类型,这个参数类型可被用在接口、类、方法上,分别称为泛型接口、泛型类、泛型方法。

1.1 为什么要引入泛型

没有泛型的Java只能通过Object强制转换成具体的类型,这种写法极其不美观,而且需要程序员去保证这个强转操作的正确性,否则极有可能在虚拟机运行的时候抛出ClassCastException。

1.2 类型擦除

Java中的泛型是伪泛型,泛型只会在程序 源码 中存在,在编译后的 class文件 中,参数类型将会被抹除(类型擦除)。

 public class ClassTest {

    public static  void  main(String[] args) {
        List<String> result = new ArrayList<>();
        result.add("test");
        System.out.println(result.get(0));
    }
}
  

上述Java代码经编译过后,会生成class文件,我们再对class文件 反编译 ,得到的程序代码如下:

 public class ClassTest {
    public ClassTest() {
    }

    public static void main(String[] var0) {
        ArrayList var1 = new ArrayList();
        var1.add("test");
        System.out.println((String)var1.get(0));
    }
}
  

这里我们可以看到,泛型中的String已经被完全擦除,并且当我们从list中取回数据时自动强转成了String。Java编译器会自动将泛型擦除,将强转添加。

 public class ClassTest {

    public static void test(List<String> args) {
    }

    public static void test(List<Integer> args) {
    }
}
  

上述代码编译不会通过,因为List和List最终都会变为List。

1.3 Signature

Signature是属性表中的一项属性,可作用于类、方法表、以及字段表。

由于Java泛型的引入,各种场景下的方法调用都可能产生影响,如在泛型类中如何获取参数化类型。

 public class ClassTest {

    public List<Double> test(List<String> args, List<Integer> args1) {
        return null;
    }
}
  

上述源码编译成class文件以后,我们在使用java -p指令来看一下字节码文件,如下图:

Signature一个重要的作用就是保存了参数化类型,这样以后通过这个属性我们就可以获取到参数化类型。

2. foreach语法

 public class ClassTest {

    public static void main(String[] args) {
        List<String> result = new ArrayList<>();
        result.add("test");
        for (String r : result) {
            System.out.println(r);
        }
    }
}
  

上述foreach语法在经过编译后,变成了使用Iterator进行遍历。

 public class ClassTest {
    public ClassTest() {
    }

    public static void main(String[] var0) {
        ArrayList var1 = new ArrayList();
        var1.add("test");
        Iterator var2 = var1.iterator();

        while(var2.hasNext()) {
            String var3 = (String)var2.next();
            System.out.println(var3);
        }

    }
}
  

通过上述我们也可以看出,如果想要使用foreach语法,该类必须要实现Iterable接口。

Java中除了上述两种语法糖,还有诸如内部类、自动装箱、自动拆箱、try语句定义和关闭资源等,分析方法均如上述,感兴趣的读者可以自行分析。

本期的Java语法糖介绍到这,我是shysh95,我们下期再见!!!

文章来源:智云一二三科技

文章标题:Java泛型擦除

文章地址:https://www.zhihuclub.com/180125.shtml

关于作者: 智云科技

热门文章

网站地图