专栏首页在周末的专栏Java语法糖(一)

Java语法糖(一)

概述

  语法糖(Syntactic Sugar):主要作用是提高编码效率,减少编码出错的机会。

  解语法糖发生在Java源码被编译成Class字节码的过程中,还原回简单的基础语法结构。

语法糖之一:泛型(Generics)

  Java中的泛型又称为类型擦除,它只在Java源码中存在,被编译成字节码后,就已经替换为原生类型了,并在相应的地方加入强制类型转换。

  例如:

public class GenericTypes {
    /*
     * 两个mothod1方法不能被编译,因为List<Integer>和List<String>被编译成class文件后都被擦除了,
     * 变成了一样的原生类型List<T>,擦除之后两个方法的签名一样。
     */
    public static void mothod1(List<Integer> list) {
        
    }
    public static void mothod1(List<String> list) {
        
    }
    
    /*
     * 在jdk1.7
     * 两个mothod2方法不能被编译,因为List<Integer>和List<String>被编译成class文件后都被擦除了,
     * 变成了一样的原生类型List<T>,擦除之后两个方法的签名一样。返回值不参与重载选择
     * 
     * Sun JDK1.6中Javac才能编译成功
     * 在Class文件格式中,只要描述符不是完全一致的两个方法就可以共存。
     */
    public static String mothod2(List<String> list) {
        return "";
    }
    public static Integer mothod2(List<Integer> list) {
        return 1;
    }
}

语法糖之二:自动拆箱和装箱、Foreach、变长参数

  例如:

public class Foreach_Varargs {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4);//变长参数(Varargs)
        int sum = 0;
        for(int i : list) { //遍历循环Foreach
            sum += i;
        }
        System.out.println(sum);
    }
    /*
     * 反编译之后的代码
     * 1、变长参数还原为数组类型的参数:Arrays.asList(...)  ---->  new Integer[]{...}
     * 2、Foreach还原为迭代器实现
     * 3、自动拆箱和装箱还原为Integer.valueOf()和Integer.intValue()方法
     * 
     public static void main(String[] args) {
        java.util.List<Integer> list = java.util.Arrays.asList(new Integer[] {
                Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3),
                Integer.valueOf(4) });
        int sum = 0;
        for (Iterator localIterator = list.iterator(); localIterator.hasNext();) {
            int i = ((Integer) localIterator.next()).intValue();
            sum += i;
        }
        System.out.println(sum);
    } 
     */
}

  一个更复杂的自动装箱拆箱的栗子:

public class Autoboxing {
    public static void main(String[] args) {
        Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Integer d = 3;
        Integer e = 321;
        Integer f = 321;
        Long g = 3L;
        System.out.println(c == d); //(1)
        System.out.println(e == f); //(2)
        System.out.println(c == (a + b)); //(3)
        System.out.println(c.equals(a + b)); //(4)
        System.out.println(g == (a + b)); //(5)
        System.out.println(g.equals(a + b)); //(6)
    }
    /*
     * 反编译后的代码
     * 
     * 包装类的“==”运算在不遇到算数运算的情况下不会自动拆箱;
     * equals方法不处理数据转型的关系。
     * 
     * 在 Java 中,== 比较的是对象引用,而 equals 比较的是值。
     * 
     * 一、(1)为true,(2)为false原因:
     *      IntegerCache:把-128到127(可调)的整数都提前实例化了,不管创建多少个这个范围内的Integer用ValueOf出来的都是同一个对象;
     *      用来节省内存和提高性能。这种 Integer缓存策略仅在自动装箱(autoboxing)的时候有用,使用构造器创建的 Integer 对象不能被缓存。
     *      这个缓存会在 Integer 类第一次被使用的时候被初始化出来.是什么原因选择这个 -128 到 127 这个范围呢?因为这个范围的整数值是使用最广泛的。
     *      Byte,Short,Long 有固定范围: -128 到 127。对于 Character, 范围是 0 到 127。除了 Integer 可以通过参数改变范围外,其它的都不行
     *      
     *      不在缓存范围的会新new Integer对象。
     * 二、(3)为true,(5)为true
     *      自动拆箱,相当于数值类型int
     * 三、(4)为true
     *      a,b先拆箱计算数值和,再将计算结果装箱为Integer
     * 四、(5)为false
     *      g为Long类型,a + b为Integer,类型不一致
     * 五、(6)为false, g为Long类型,a + b为Integer,类型不一致,返回false
            public boolean equals(Object obj) {
                if (obj instanceof Long) {
                    return value == ((Long)obj).longValue();
                }
                return false;
            }     
     *      
     public class Autoboxing {
       public static void main(String[] args) {
          Integer a = Integer.valueOf(1);
          Integer b = Integer.valueOf(2);
          Integer c = Integer.valueOf(3);
          Integer d = Integer.valueOf(3);
          Integer e = Integer.valueOf(321);
          Integer f = Integer.valueOf(321);
          Long g = Long.valueOf(3L);
          System.out.println(c == d);
          System.out.println(e == f);
          System.out.println(c.intValue() == a.intValue() + b.intValue());
          System.out.println(c.equals(Integer.valueOf(a.intValue() + b.intValue())));
          System.out.println(g.longValue() == (long)(a.intValue() + b.intValue()));
          System.out.println(g.equals(Integer.valueOf(a.intValue() + b.intValue())));
       }
    }
    */
}

语法糖之三:条件编译

  栗子:

public class ifdef {
    public static void main(String[] args) {
        final boolean isCompile = true;
        if(isCompile) {
            System.out.println("11111");
        } else {
            System.out.println("2222");
        }
    }
    /*
     * 条件编译
     * System.out.println("2222"); 不会编译
     * Java只能实现语句基本块级别的条件编译,而无法实现根据条件调整整个Java类的结构。
     * 
     * 反编译后的代码:
     * public class ifdef {
           public static void main(String[] args) {
              boolean isCompile = true;
              System.out.println("11111");
           }
        }
     */
}

除以上外,语法糖还有:内部类、枚举类、断言语句、对枚举和字符串的switch支持(1.7)、try语句中定义和关闭资源(1.7)等,接下来继续Java语法糖系列。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java并发编程--AQS

      抽象队列同步器(AbstractQueuedSynchronizer,简称AQS)是用来构建锁或者其他同步组件的基础框架,它使用一个整型的volatile变...

    在周末
  • Java并发编程--Semaphore

      信号量(Semaphore)控制同时访问资源的线程数量,支持公平和非公平两种方式获取许可。

    在周末
  • Java内存模型

      重排序是指编译器或处理器为了提高程序性能而对指令序列进行重新排序的一种手段。重排序可以导致操作延时或程序看似乱序执行,给程序运行的结果带来一定的不确定性。

    在周末
  • 【小家java】大杂烩---那些年我们一起躺过的坑

    此篇博文没有具体的主题,主要针对于平时开发过程中遇到的一些小问题的记录,并且大都从源码的角度去解释为什么会报错。并且此篇博文是持续更新中。。。

    YourBatman
  • Java中Integer的详解

    在Java中有int和integer两种类型,简单的说Integer是int的引用类型,但是这个引用的类型比较特殊,下面看几个demo:

    付威
  • Flink SQL vs Spark SQL

    Spark已经在大数据分析领域确立了事实得霸主地位,而Flink则得到了阿里系的亲赖前途一片光明。我们今天会SparkSQL和FlinkSQL的执行流程进行一个...

    麒思妙想
  • 再谈Integer对象比较

    在上一篇文章中介绍了Integer的特性及面试中常考的几个知识点,本篇文章再做些扩充。

    小诸葛
  • 奇怪的Java题:为什么128 == 128返回为false,而127 == 127会返回为true?

    奇怪的Java题:为什么128 == 128返回为false,而127 == 127会返回为true?

    互扯程序
  • 夯实Java基础系列8:深入理解Java内部类及其实现原理

    本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看

    Java技术江湖
  • 搞清楚一道关于Integer的面试题

    面试题3中的a=99相当于a=new Integer(99);重新给把一个新的对象引用地址给了a,所以a变了,最后输出是99。

    用户4143945

扫码关注云+社区

领取腾讯云代金券