美文网首页
Java 语法糖

Java 语法糖

作者: RobertCrazying | 来源:发表于2018-02-13 09:24 被阅读15次

    前言

    Java 最早诞生于 1995 年,直到现在都还是最热门的语言之一,那么Java 是怎么满足人们提出的各种后辈语言们的实用功能的呢?语法糖就是其中方式。

    解语法糖

    Java 为了保证向后兼容又要实现一些新特性非常很不容易,事实上JVM 并不认识这些语法,这些语法糖其实都是编译前的产物,编译阶段就会解语法糖。下面讲一下常见的几种语法糖。

    switch 支持 String

    switch 本身就支持 int , char 等基本数据类型,在 jdk 1.7 之后 switch 也开始支持 String 和枚举 Enum 类型了,其实内部就是通过语法糖的方式实现的。
    反编译一段代码就能看到内部是通过 String 的 hashCode 和 equals 方法实现的。

    public class switchDemoString
        {
            public switchDemoString()
            {
            }
            public static void main(String args[])
            {
                String str = "world";
                String s;
                switch((s = str).hashCode())
                {
                default:
                    break;
                case 99162322:
                    if(s.equals("hello"))
                        System.out.println("hello");
                    break;
                case 113318802:
                    if(s.equals("world"))
                        System.out.println("world");
                    break;
                }
            }
        }
    

    这里在 case 完 hashCode 之后还有一次 equals 方法的检查,这是因为哈希可能发生碰撞冲突即两个对象的哈希值一样,所以 switch String 的性能没有基本数据好。

    泛型

    Java 的泛型是通过类型擦除实现的,即泛型的类型检查只在编辑前检查限制,编译成字节码的时候有个类型擦除的过程,JVM 并不认识泛型类型。
    以下代码:

        Map<String, String> map = new HashMap<String, String>();  
        map.put("name", "hollis");  
        map.put("wechat", "Hollis");  
        map.put("blog", "www.hollischuang.com");
    

    解语法糖之后会变成:

        Map map = new HashMap();  
        map.put("name", "hollis");  
        map.put("wechat", "Hollis");  
        map.put("blog", "www.hollischuang.com");
    

    自动装箱和拆箱

        自动装箱的代码
        public static void main(String[] args) {
            int i = 10;
            Integer n = i;
        }
    
       反编译后代码如下:
       public static void main(String args[])
        {
            int i = 10;
            Integer n = Integer.valueOf(i);
        }
    

    三个点

        public static void print(String... strs)
        {
            for (int i = 0; i < strs.length; i++)
            {
                System.out.println(strs[i]);
            }
        }
    
    反编译后代码:
        public static transient void print(String strs[])
        {
            for(int i = 0; i < strs.length; i++)
                System.out.println(strs[i]);
    
        }
    

    可以看到 ... 相当于是数组实现。

    枚举

    public enum t {
            SPRING,SUMMER;
        }
    
    然后我们使用反编译,看看这段代码到底是怎么实现的,反编译后代码内容如下:
    
       public final class T extends Enum
        {
            private T(String s, int i)
            {
                super(s, i);
            }
            public static T[] values()
            {
                T at[];
                int i;
                T at1[];
                System.arraycopy(at = ENUM$VALUES, 0, at1 = new T[i = at.length], 0, i);
                return at1;
            }
    
            public static T valueOf(String s)
            {
                return (T)Enum.valueOf(demo/T, s);
            }
    
            public static final T SPRING;
            public static final T SUMMER;
            private static final T ENUM$VALUES[];
            static
            {
                SPRING = new T("SPRING", 0);
                SUMMER = new T("SUMMER", 1);
                ENUM$VALUES = (new T[] {
                    SPRING, SUMMER
                });
            }
        }
    

    内部类

    内部类也是个编译时的概念,因为编译之后内部类也是会生成一个
    class 文件

    总结

    Java 的各种语法糖在编译时就规避了很多错误,可以把 bug 早早地扼杀掉,在结合 IDEA 等现代 IDE 可以大大提高开发者的编程体验。在探究内部实现时可以看到都是很巧妙的实现。

    参考链接:https://mp.weixin.qq.com/s/BNWEE7wFc6ZvDAqJQrZRaA

    相关文章

      网友评论

          本文标题:Java 语法糖

          本文链接:https://www.haomeiwen.com/subject/tfwltftx.html