本文目錄一覽:
- 1、Java 中 Enum 如何繼承?
- 2、在《Effective Java》中,為什麼推薦使用enum來實現單例模式
- 3、為什麼java中用枚舉實現單例模式會更好
- 4、Java 枚舉型為什麼是靜態的,以及是怎麼實現的
Java 中 Enum 如何繼承?
Java Enum是不能繼承的,以下是解釋:
枚舉類使用enum定義後在編譯後默認繼承了java.lang.Enum類,而不是普通的繼承Object類。enum聲明類繼承了Serializable和Comparable兩個介面。且採用enum聲明後,該類會被編譯器加上final聲明(同String),故該類是無法繼承的。枚舉類的內部定義的枚舉值就是該類的實例(且必須在第一行定義,當類初始化時,這些枚舉值會被實例化)。
Java 5新增的enum關鍵詞,可以定義枚舉類。該類是一個特殊的類,可以定義自己的field、方法、可以實現介面,也可以定義自己的構造器。
在《Effective Java》中,為什麼推薦使用enum來實現單例模式
單例模式實現方式有很多:在第一次使用的時候創建(構造函數中判斷是否已經有實例存在),在類載入的時候用靜態塊兒創建(靜態塊初始化),在應用啟動的時候創建。
在單線程中,基本大同小異,保證類的實例在整個應用中只有一個,都是沒問題的。
但是在多線程環境下,什麼時候創建這個實例是要考慮線程安全的。
枚舉類型最大的特點就是:構造函數是private修飾的,也就是不能對其進行new,對象的實例都是預定義的,也就是在類載入的時候都是定義好了的,不會給其它調用去創建實例的機會。
結論是,可以模擬這個思路去創建單例,不一定非得用枚舉,但是推薦用使用定義枚舉的方式去實現單例模式
為什麼java中用枚舉實現單例模式會更好
單例模式實現方式有很多:在第一次使用的時候創建(構造函數中判斷是否已經有實例存在),在類載入的時候用靜態塊兒創建(靜態塊初始化),在應用啟動的時候創建。
在單線程中,基本大同小異,保證類的實例在整個應用中只有一個,都是沒問題的。
但是在多線程環境下,什麼時候創建這個實例是要考慮線程安全的。
枚舉類型最大的特點就是:構造函數是private修飾的,也就是不能對其進行new,對象的實例都是預定義的,也就是在類載入的時候都是定義好了的,不會給其它調用去創建實例的機會。
結論是,可以模擬這個思路去創建單例,不一定非得用枚舉,但是推薦用使用定義枚舉的方式去實現單例模式
Java 枚舉型為什麼是靜態的,以及是怎麼實現的
是的,Java枚舉型是靜態常量,隱式地用static final修飾過。
確切地說,Java枚舉型是「靜態常量」,這裡面包含了兩層意思:
枚舉型中的實例隱式地用static final修飾過。
枚舉型作為某個類中的成員欄位也隱式地用static final修飾過。
public class Traffic{
public enum Light{GREEN,YELLOW,RED}
}
還是你上面這個代碼,反編譯一下,你就能看到–編譯器背著你偷偷做了哪些手腳:
/*
* Decompiled with CFR 0_118.
*/
package com.ciaoshen.thinkinjava.chapter19;
public class Traffic {
public static final class Light
extends EnumLight {
public static final /* enum */ Light GREEN = new Light();
public static final /* enum */ Light YELLOW = new Light();
public static final /* enum */ Light RED = new Light();
private static final /* synthetic */ Light[] $VALUES;
public static Light[] values() {
return (Light[])$VALUES.clone();
}
public static Light valueOf(String string) {
return Enum.valueOf(Light.class, string);
}
private Light() {
super(string, n);
}
static {
$VALUES = new Light[]{GREEN, YELLOW, RED};
}
}
}
首先,枚舉型Light是個實實在在的類。繼承自基類EnumLight。然後在你不知情的情況下,偷偷加了static final修飾詞。
然後三個枚舉實例GREEN, YELLOW, RED也確確實實是Light的實例。然而前面也加上了static final。
然後構造器也被偷偷地閹割成private。這種實例控制手段,是不是在單例器模式里也見過?所以枚舉也是實現單例器的一種方法。
然後編譯器還偷偷合成了Light[]數組,一個values( )方法,一個valueOf( )方法。這個values( )在Enum的文檔里都找不到。
如果在Enum里定義一個相關方法,你還會看到一個匿名內部類:
public enum Light{
GREEN{public void show(){System.out.println(“Green”);}},
YELLOW{public void show(){System.out.println(“Yellow”);}},
RED{public void show(){System.out.println(“Red”);}};
}
反編譯的結果如下:
/*
* Decompiled with CFR 0_118.
*/
package com.ciaoshen.thinkinjava.chapter18;
import java.io.PrintStream;
public class Light
extends EnumLight {
public static final /* enum */ Light GREEN = new Light(“GREEN”, 0){
public void show() {
System.out.println(“Green”);
}
};
public static final /* enum */ Light YELLOW = new Light(“YELLOW”, 1){
public void show() {
System.out.println(“Yellow”);
}
};
public static final /* enum */ Light RED = new Light(“RED”, 2){
public void show() {
System.out.println(“Red”);
}
};
private static final /* synthetic */ Light[] $VALUES;
public static Light[] values() {
return (Light[])$VALUES.clone();
}
public static Light valueOf(String string) {
return Enum.valueOf(Light.class, string);
}
private Light() {
super(string, n);
}
static {
$VALUES = new Light[]{GREEN, YELLOW, RED};
}
}
總之,Java的Enum枚舉型整個就是一個大大的「語法糖」。明明是一個完整的類,但只向用戶暴露幾個靜態常量,隱藏掉大部分實現的細節。
原創文章,作者:J33MY,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/127346.html