> 技术文档 > JAVA语法糖

JAVA语法糖


大纲

JAVA语法糖让程序更加简洁,有更高的可读性。

#mermaid-svg-YU4EdawH6y9LMul5 {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-YU4EdawH6y9LMul5 .error-icon{fill:#552222;}#mermaid-svg-YU4EdawH6y9LMul5 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YU4EdawH6y9LMul5 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-YU4EdawH6y9LMul5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YU4EdawH6y9LMul5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YU4EdawH6y9LMul5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YU4EdawH6y9LMul5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YU4EdawH6y9LMul5 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YU4EdawH6y9LMul5 .marker.cross{stroke:#333333;}#mermaid-svg-YU4EdawH6y9LMul5 svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YU4EdawH6y9LMul5 .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YU4EdawH6y9LMul5 .cluster-label text{fill:#333;}#mermaid-svg-YU4EdawH6y9LMul5 .cluster-label span{color:#333;}#mermaid-svg-YU4EdawH6y9LMul5 .label text,#mermaid-svg-YU4EdawH6y9LMul5 span{fill:#333;color:#333;}#mermaid-svg-YU4EdawH6y9LMul5 .node rect,#mermaid-svg-YU4EdawH6y9LMul5 .node circle,#mermaid-svg-YU4EdawH6y9LMul5 .node ellipse,#mermaid-svg-YU4EdawH6y9LMul5 .node polygon,#mermaid-svg-YU4EdawH6y9LMul5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YU4EdawH6y9LMul5 .node .label{text-align:center;}#mermaid-svg-YU4EdawH6y9LMul5 .node.clickable{cursor:pointer;}#mermaid-svg-YU4EdawH6y9LMul5 .arrowheadPath{fill:#333333;}#mermaid-svg-YU4EdawH6y9LMul5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YU4EdawH6y9LMul5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YU4EdawH6y9LMul5 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-YU4EdawH6y9LMul5 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-YU4EdawH6y9LMul5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YU4EdawH6y9LMul5 .cluster text{fill:#333;}#mermaid-svg-YU4EdawH6y9LMul5 .cluster span{color:#333;}#mermaid-svg-YU4EdawH6y9LMul5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YU4EdawH6y9LMul5 :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}语法糖switch支持String与枚举泛型变长参数自动拆装箱枚举类内部类条件编译断言数值字面量for-eachtry-with-resourcelambda表达式

switch支持String与枚举

字符串的 switch 是通过equals()和hashCode()方法来实现的。

Code sharing 方式为每个泛型类型创建唯一的字节码表示,并且将该泛型类型的实例都映射到这个唯一的字节码表示上。将多种泛型类形实例映射到唯一的字节码表示是通过类型擦除(type erasue)实现的。

虚拟机中没有泛型,只有普通类和普通方法,所有泛型类的类型参数在编译时都会被擦除,泛型类并没有自己独有的Class类对象。比如并不存在List.class或是List.class,而只有List.class。

泛型

不同的编译器对于泛型的处理方式是不同的,通常情况下,一个编译器处理泛型有两种方式:Code specialization和Code sharing。C++和 C#是使用Code specialization的处理机制,而 Java 使用的是Code sharing的机制。

  • 泛型遇到重载:编译不过,因为泛型编译后类型被擦除了
  • 当泛型遇到 catch:泛型的类型参数不能用在 Java 异常处理的 catch 语句中。因为异常处理是由 JVM 在运行时刻来进行的。
  • 当泛型内包含静态变量:由于经过类型擦除,所有的泛型类实例都关联到同一份字节码上,泛型类的静态变量是共享的。

变长参数

可变参数在被使用的时候,他首先会创建一个数组,数组的长度就是调用该方法是传递的实参的个数,然后再把参数值全部放到这个数组当中,然后再把这个数组作为参数传递到被调用的方法中。

自动拆装箱

装箱过程是通过调用包装器的 valueOf 方法实现的,而拆箱过程是通过调用包装器的 xxxValue 方法实现的。

对象相等比较:在 Java 5 中,在 Integer 的操作上引入了一个新功能来节省内存和提高性能。整型对象通过使用相同的对象引用实现了缓存和重用。

适用于整数值区间-128 至 +127。
只适用于自动装箱。使用构造函数创建对象不适用。

枚举类

当我们使用enum来定义一个枚举类型的时候,编译器会自动帮我们创建一个final类型的类继承Enum类,所以枚举类型不能被继承。

内部类

内部类又称为嵌套类,可以把内部类理解为外部类的一个普通成员。

  • 匿名内部类、局部内部类、静态内部类也是通过桥方法来获取 private 属性。
  • 静态内部类没有this$0的引用
  • 匿名内部类、局部内部类通过复制使用局部变量,该变量初始化之后就不能被修改。

条件编译

Java 语法的条件编译,是通过判断条件为常量的 if 语句实现的。其原理也是 Java 语言的语法糖。根据 if 判断条件的真假,编译器直接把分支为 false 的代码块消除。通过该方式实现的条件编译,必须在方法体内实现,而无法在整个 Java 类的结构或者类的属性上进行条件编译,这与 C/C++的条件编译相比,确实更有局限性。在 Java 语言设计之初并没有引入条件编译的功能,虽有局限,但是总比没有更强。

断言

Java 在执行的时候默认是不启动断言检查的(这个时候,所有的断言语句都将忽略!),如果要开启断言检查,则需要用开关-enableassertions或-ea来开启。

-enableassertions会设置$assertionsDisabled 字段的值。

数值字面量

在 java 7 中,数值字面量,不管是整数还是浮点数,都允许在数字之间插入任意多个下划线。这些下划线不会对字面量的数值产生影响,目的就是方便阅读。

for-each

for-each 的实现原理其实就是使用了普通的 for 循环和迭代器。

Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出java.util.ConcurrentModificationException异常。

try-with-resource

那些我们没有做的关闭资源的操作,编译器都帮我们做了。

lambda表达式

lambda 表达式的实现其实是依赖了一些底层的 api,在编译阶段,编译器会把 lambda 表达式进行解糖,转换成调用内部 api 的方式。