深入Java虚拟机-- Java语法糖
概述:语法糖(Syntactic Sugar),是编程语言提供的一些方便程序员开发的语法,这些语法在编译期间
编译以后生成的SyntacticSugarLearning.class文件,反编译后,如下:
从反编译以后的Java代码中可以看到,泛型Map<String,String>,经过编译以后,变成了Map;在获取map中的值时,
经过编译以后,生成了2个Class文件:
OutClass.class
OutClass$InClass.class
如下图所示:
OutClass$InClass.class代码如下:
内部类经过编译以后,生成了2个Class文件。
概述:语法糖(Syntactic Sugar),是编程语言提供的一些方便程序员开发的语法,这些语法在编译期间
会按照预先的规则,被还原成基本的Java语法。主要目的是方便程序员开发使用,减少出错。
package com.yangcq.action;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author yangcq
* @Java语法糖学习笔记
* @version 20160720
*
*/
public class SyntacticSugarLearning {
public static void main(String[] args) {
/**
* 语法糖,也叫糖衣语法,是值在计算机语言中添加的某种语法,这种语法对语言的功能
* 并没有影响,但是会方便程序员使用。
* Java中常见的语法糖主要有:
* 1,泛型
* 2,变长参数
* 3,条件编译
* 4,自动拆装箱
* 5,内部类
*
* 语法糖在Java程序的编译阶段就会被还原成基础语法结构,这样就能够被JVM支持。这个
* 过程叫做解语法糖
*
* 下面我们以泛型为例来进行说明:
*
* 泛型是JDK1.5之后引入的新特性,在泛型出现之前,只能通过Object是所有类型的父类和
* 类型强制转换这2个特性来实现类似泛型的功能。这样实现的泛型功能只有在程序运行期
* 才能知道Object真正的类型。在编译期间,JVM无法检查这个Object的强制类型转换是否
* 正确,这样就把风险转接到了程序运行期中。
* JDK1.5之后引入的泛型,实际上只在程序源代码中存在,在编译后的字节码文件中,就已经
* 被替换为了原来的原生类型,并且在相应地方插入了强制类型转换代码。因此对于运行期的
* Java来说,HashMap<String,String> 和 HashMap<Integer,Integer>,是同一个类。
*
* 下面通过一个测试程序来认识以下泛型
*
*/
Map<String,String> map = new HashMap<String,String>();
map.put("name", "yangcq");
System.out.println(map.get("name"));
}
}
编译以后生成的SyntacticSugarLearning.class文件,反编译后,如下:
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
public class SyntacticSugarLearning
{
public static void main(String[] args)
{
Map map = new HashMap();
map.put("name", "yangcq");
System.out.println((String)map.get("name"));
}
}
从反编译以后的Java代码中可以看到,泛型Map<String,String>,经过编译以后,变成了Map;在获取map中的值时,
进行了强制类型转换
(String)map.get("name")
Java语法糖的另一个经典应用:内部类
相信大家对Java内部类都有一定的了解了。内部类是指:在外部类中定义的Java类。
java内部类分为: 成员内部类、静态嵌套类、方法内部类、匿名内部类 。
这里我们主要从Java语法糖的角度来认识内部类。代码如下:
//外部类
public class OutClass {
private String username = "yangcq";
//内部类
class InClass {
public void printUsername() {
System.out.println("username : " + username);
}
}
}
经过编译以后,生成了2个Class文件:
OutClass.class
OutClass$InClass.class
如下图所示:
OutClass.class代码如下:
package com.spider.java;
import java.io.PrintStream;
public class OutClass
{
private String username = "yangcq";
class InClass
{
public void printUsername() {
System.out.println("username : " + OutClass.this.username);
}
}
}
OutClass$InClass.class代码如下:
package com.spider.java;
import java.io.PrintStream;
class InClass
{
public void printUsername()
{
System.out.println("username : " + OutClass.access$0(this.this$0));
}
}
内部类经过编译以后,生成了2个Class文件。