jvm提供的语法糖

一、默认构造方法

       如果不写无参构造方法,在编译完的字节码中会自动填上无参构造方法。

 

二、自动拆箱装箱

       

    Integer  a = 4;(自动装箱)

    int  b  =  a;(自动拆箱)

 

三、泛型擦除

    在编译期会将所有的泛型去处,在编译后的字节码中一直会以Object类型存在,在调用的时候会使用 jvm 指令 checkcast 将Object类型强制转换为泛型类。

    List<Integer> a = new ArrayList<>();
     a.add(10); //实际上调用的是 a.add(Object o)
    Integer b = a.get(0);  //实际上调用的是 Obejct e = a.get(int index);
                           Integer b = (Integer)e; 
    
    int c = a.get(0);  //实际上调用的是 Obejct e = a.get(int index);
                           int c = (Integer)e.intValue(); 

     

    但是字节码文件中的局部变量类型表中的泛型不会被擦除,里面存放了参数类型的泛型

 

 

四、泛型反射

     

 

五、可变参数

     jdk1.5添加的新特性

    //方法中的String ... arg 等价于String[]  arg;
    public void get(String ... arg){ 

    }

 

六、foreach

   int[] a = {1,2,4};
    for(int b : a){
       System.out.println(b);
    }

编译后的代码如下

   int[] a = new int[]{1,2,4};
    for(int i=0;i < a.length ; i++){
       System.out.println(a[i]);
    }

 

七、switch可填写String

   jdk1.7出现的。实际上switch是不支持String的,只不过编译后会计算相应的hashCode,根据相应的hashCode找对应的字符串,为了避免hash冲突,再进行equals对比字符串是否相同。

public static void choose(String str){
    switch(str){
    case "hello" :
      System.out.println("h");
      break;
   case "world":
      System.out.println("w");
      break;
   }
}

 

编译后的代码如下:

 

 

 

 

 

八、switch可填写enum

   jdk1.7出现的

 

 

 

 编译后

 

 

 其中的合成类是不可见的拆出来大概如下:

static class $MAP{
    static int[] map = new int[2];      
        static {
              map[Num.ONE.ordinal()] = 1;
              map[Num.TWO.ordinal()] = 2;  
        }
    }    
//null.$SwitchMap$test$test1$TestPath$Num[num.ordinal()]可以替换为如下代码以供参考
  $MAP.map[num.ordinal]

 

九、枚举

 编译后会出现隐藏的 values() 方法,以及 valueOf() 方法,并且有私有的构造方法,也是简易的单例模式。

 

十、try-with-resources

作用是会自动关闭资源占用,前提是资源对象需要实现AutoCloseable接口,例如InputStream、OutputStream、Connection、Statement等接口都实现了AutoCloseable,使用try-with-resources可以不用写finally语句块,编译器会帮助生成关闭资源代码:

try(资源变量 = 创建资源对象){

}catch(){

}

如下代码:

public static void main(String[] args) {

        try(InputStream is = new FileInputStream("test.txt")){
            System.out.println(is);
        }catch(Exception o){
            o.printStackTrace();
        }
}

编译过后为

public static void main(String[] args) {        
    try {            
        InputStream is = new FileInputStream("test.txt");            
        Throwable var2 = null;
            try {
                System.out.println(is);
            } catch (Throwable var12) {
                var2 = var12;//var2为我们代码出现的异常
                throw var12;
            } finally {
                if (is != null) {//判断资源不为空
                    if (var2 != null) {//判断我们代码是否有异常
                        try {
                            is.close();
                        } catch (Throwable var11) {
                            var2.addSuppressed(var11);//如果close方法出现异常,作为被压制异常添加
                        }
                    } else {
                        is.close();//如果我们代码没有异常,close出现的异常就是最后catch抓住的异常
                    }
                }

            }
        } catch (Exception var14) {
            var14.printStackTrace();
        }

    }

 

posted @ 2021-04-24 15:41  香吗  阅读(97)  评论(0)    收藏  举报