作者:danchu
http://blog.csdn.net/danchu/article/details/54986442

語法糖(Syntactic Sugar),也稱糖衣語法,指在計算機語言中添加的某種語法,這種語法對語言本身功能來說沒有什么影響,只是為了方便程式員的開發,提高開發效率,說白了,語法糖就是對現有語法的一個封裝,
Java作為一種與平臺無關的高級語言,當然也含有語法糖,這些語法糖并不被虛擬機所支持,在編譯成位元組碼階段就自動轉換成簡單常用語法,
一般來說Java中的語法糖主要有以下幾種:
-
泛型與型別擦除
-
自動裝箱與拆箱
-
變長引數
-
增強for回圈
-
內部類
-
列舉類
泛型與型別擦除
Java語言并不是一開始就支持泛型的,在早期的JDK中,只能通過Object類是所有型別的父類和強制型別轉換來實作泛型的功能,強制型別轉換的缺點就是把編譯期間的問題延遲到運行時,JVM并不能為我們提供編譯期間的檢查,
在JDK1.5中,Java語言引入了泛型機制,但是這種泛型機制是通過型別擦除來實作的,即Java中的泛型只在程式源代碼中有效(源代碼階段提供型別檢查),在編譯后的位元組碼中自動用強制型別轉換進行替代,也就是說,Java語言中的泛型機制其實就是一顆語法糖,相較與C++、C#相比,其泛型實作實在是不那么優雅,
/**
* 在源代碼中存在泛型
*/
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("hello","你好");
String hello = map.get("hello");
System.out.println(hello);
}
當上述源代碼被編譯為class檔案后,泛型被擦除且引入強制型別轉換
public static void main(String[] args) {
HashMap map = new HashMap(); //型別擦除
map.put("hello", "你好");
String hello = (String)map.get("hello");//強制轉換
System.out.println(hello);
}
自動裝箱與拆箱
Java中的自動裝箱與拆箱指的是基本資料型別與他們的包裝型別之間的相互轉換,
我們知道Java是一門面向物件的語言,在Java世界中有一句話是這么說的:“萬物皆物件”,但是Java中的基本資料型別卻不是物件,他們不需要進行new操作,也不能呼叫任何方法,這在使用的時候有諸多不便,因此Java為這些基本型別提供了包裝類,并且為了使用方便,提供了自動裝箱與拆箱功能,自動裝箱與拆箱在使用的程序中,其實是一個語法糖,內部還是呼叫了相應的函式進行轉換,
下面代碼演示了自動裝箱和拆箱功能
public static void main(String[] args) {
Integer a = 1;
int b = 2;
int c = a + b;
System.out.println(c);
}
經過編譯后,代碼如下
public static void main(String[] args) {
Integer a = Integer.valueOf(1); // 自動裝箱
byte b = 2;
int c = a.intValue() + b;//自動拆箱
System.out.println(c);
}
變長引數
所謂變長引數,就是方法可以接受長度不定確定的引數,變長引數特性是在JDK1.5中引入的,使用變長引數有兩個條件,一是變長的那一部分引數具有相同的型別,二是變長引數必須位于方法引數串列的最后面,變長引數同樣是Java中的語法糖,其內部實作是Java陣列,
public class Varargs {
public static void print(String... args) {
for(String str : args){
System.out.println(str);
}
}
public static void main(String[] args) {
print("hello", "world");
}
}
編譯為class檔案后如下,從中可以很明顯的看出變長引數內部是通過陣列實作的
public class Varargs {
public Varargs() {
}
public static void print(String... args) {
String[] var1 = args;
int var2 = args.length;
//增強for回圈的陣列實作方式
for(int var3 = 0; var3 < var2; ++var3) {
String str = var1[var3];
System.out.println(str);
}
}
public static void main(String[] args) {
//變長引數轉換為陣列
print(new String[]{"hello", "world"});
}
}
增強for回圈
增強for回圈與普通for回圈相比,功能更強并且代碼更簡潔,增強for回圈的物件要么是一個陣列,要么實作了Iterable介面,這個語法糖主要用來對陣列或者集合進行遍歷,其在回圈程序中不能改變集合的大小,
public static void main(String[] args) {
String[] params = new String[]{"hello","world"};
//增強for回圈物件為陣列
for(String str : params){
System.out.println(str);
}
List<String> lists = Arrays.asList("hello","world");
//增強for回圈物件實作Iterable介面
for(String str : lists){
System.out.println(str);
}
}
編譯后的class檔案為
public static void main(String[] args) {
String[] params = new String[]{"hello", "world"};
String[] lists = params;
int var3 = params.length;
//陣列形式的增強for退化為普通for
for(int str = 0; str < var3; ++str) {
String str1 = lists[str];
System.out.println(str1);
}
List var6 = Arrays.asList(new String[]{"hello", "world"});
Iterator var7 = var6.iterator();
//實作Iterable介面的增強for使用iterator介面進行遍歷
while(var7.hasNext()) {
String var8 = (String)var7.next();
System.out.println(var8);
}
}
內部類
內部類就是定義在一個類內部的類 Java語言中之所以引入內部類,是因為有些時候一個類只在另一個類中有用,我們不想讓其在另外一個地方被使用,內部類之所以是語法糖,是因為其只是一個編譯時的概念,一旦編譯完成,編譯器就會為內部類生成一個單獨的class檔案,名為outer$innter.class,
public class Outer {
class Inner{
}
}
使用javac編譯后,生成兩個class檔案Outer.class和Outer$Inner.class,其中Outer$Inner.class的內容如下:
class Outer$Inner {
Outer$Inner(Outer var1) {
this.this$0 = var1;
}
}
內部類分為四種:成員內部類、區域內部類、匿名內部類、靜態內部類,每一種都有其用法,這里就不介紹了
列舉型別
列舉型別就是一些具有相同特性的類常量 java中類的定義使用class,列舉類的定義使用enum,在Java的位元組碼結構中,其實并沒有列舉型別,列舉型別只是一個語法糖,在編譯完成后被編譯成一個普通的類,這個類繼承java.lang.Enum,并被final關鍵字修飾,
public enum Fruit {
APPLE,ORINGE
}
使用jad對編譯后的class檔案進行反編譯后得到:
//繼承java.lang.Enum并宣告為final
public final class Fruit extends Enum
{
public static Fruit[] values()
{
return (Fruit[])$VALUES.clone();
}
public static Fruit valueOf(String s)
{
return (Fruit)Enum.valueOf(Fruit, s);
}
private Fruit(String s, int i)
{
super(s, i);
}
//列舉型別常量
public static final Fruit APPLE;
public static final Fruit ORANGE;
private static final Fruit $VALUES[];//使用陣列進行維護
static
{
APPLE = new Fruit("APPLE", 0);
ORANGE = new Fruit("ORANGE", 1);
$VALUES = (new Fruit[] {
APPLE, ORANGE
});
}
}
Java遠不止這些語法糖,JDK7、JDK8添加的新特性都有很多高級的語法糖,
近期熱文推薦:
1.Java 15 正式發布, 14 個新特性,重繪你的認知!!
2.終于靠開源專案弄到 IntelliJ IDEA 激活碼了,真香!
3.我用 Java 8 寫了一段邏輯,同事直呼看不懂,你試試看,,
4.吊打 Tomcat ,Undertow 性能很炸!!
5.《Java開發手冊(嵩山版)》最新發布,速速下載!
覺得不錯,別忘了隨手點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/173100.html
標籤:Java
下一篇:CDH5部署三部曲之三:問題總結
