一、文章序言
Java中引用類(lèi)型:數(shù)組、類(lèi)、接口、枚舉、注解
枚舉這個(gè)既熟悉又陌生的東西具體再哪里可以使用呢?
什么是枚舉?
枚舉是一個(gè)引用類(lèi)型,枚舉就是一個(gè)規(guī)定了取值范圍的變量類(lèi)型。
枚舉變量不能使用其他的數(shù)據(jù),只能使用枚舉中常量賦值。提高程序安全性;
//格式:
public enum 枚舉名{
//枚舉的取值范圍
//枚舉中可以生命方法
}
枚舉的使用場(chǎng)景介紹?
1、最常見(jiàn)的情況如星期,相關(guān)變量我們會(huì)在Java里面重復(fù)使用,在這里我們就可以來(lái)定義一個(gè)叫做“星期”的枚舉。
public enum Day
{
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,THURSDAY, FRIDAY, SATURDAY
}
如果不定義成枚舉,各位的寫(xiě)法就千奇百怪了,比如“周一”、“星期一”、“Monday”等,寫(xiě)法千奇百怪,定義枚舉一目了然。
2、比如說(shuō)季節(jié)的春夏秋冬,我們同樣可以定義一個(gè)這樣的變量來(lái)存儲(chǔ)對(duì)應(yīng)的季節(jié)。
public enum Season {
SPRING,
SUMMER,
AUTUMN,
WINTER;
}
3、英雄聯(lián)盟里面,有很多職業(yè),比如說(shuō)”戰(zhàn)士“、”法師“、”射手“……等職業(yè)。我們就可以定義一個(gè)叫”職業(yè)“的枚舉類(lèi)型;后臺(tái)再其它地方哪里需要直接引用即可;
總結(jié):枚舉里面定義的就相當(dāng)于是已經(jīng)生成且固定的對(duì)象,你可以直接使用;如果Java代碼里面與如上需要定義的常量可以直接定義一個(gè)枚舉類(lèi);
定義枚舉類(lèi)型時(shí)本質(zhì)上就是定義一個(gè)類(lèi)別,只不過(guò)很多細(xì)節(jié)由編譯器幫我們完成了,所以某些程度上,enum關(guān)鍵字的作用 就像是class或interface
1 枚舉的本質(zhì):其實(shí)就是終止類(lèi),并繼承Enum抽象類(lèi)。
2 枚舉中的變量,其實(shí)就是一個(gè)當(dāng)前類(lèi)型的靜態(tài)常量。
解釋?zhuān)?/p>
當(dāng)我們使用“enum”定義枚舉類(lèi)型時(shí),實(shí)質(zhì)上我們定義出來(lái)的類(lèi)型繼承自java.lang.Enum類(lèi)型,而枚舉的成員其實(shí)就是我們定義的枚舉類(lèi)型的一 個(gè)實(shí)例(Instance),他們都被預(yù)設(shè)為final,所以我們無(wú)法改變他們,他們也是static成員,所以我們可以通過(guò)類(lèi)型名稱(chēng)直接使用他們,當(dāng)然最重要的,他們都是公開(kāi)的(public)。
二、代碼實(shí)踐
先定義一個(gè)枚舉:季節(jié)枚舉
//聲明一個(gè)表示季節(jié)的枚舉
public enum Season {
SPRING,
SUMMER,
AUTUMN,
WINTER;
}
枚舉可以搭配switch語(yǔ)句使用:案例如下
public class TestSeasonEnum {
public static void main(String[] args) {
Season season = Season.SPRING;
//switch小括號(hào)中的表達(dá)式類(lèi)型可以是枚舉類(lèi)型
switch(season){
//每個(gè)case后的常量直接寫(xiě)枚舉的取值范
case SPRING:
System.out.println("春天");
break;
case SUMMER:
System.out.println("夏天");
break;
case AUTUMN:
System.out.println("秋天");
break;
case WINTER:
System.out.println("冬天");
break;
}
}
}
輸出結(jié)果
春天
為了加深理解,再舉例一個(gè)錯(cuò)誤的用法
? An enum switch case label must be the unqualified name of an enumeration constant
注意,在switch中,不能使用枚舉類(lèi)名稱(chēng),因?yàn)榫幾g器會(huì)根據(jù)switch()的類(lèi)型來(lái)判定每個(gè)枚舉類(lèi)型,在case中必須直接給出與()相同類(lèi)型的枚舉選項(xiàng),而不能再有類(lèi)型。
代碼如上可以直接測(cè)試,建議實(shí)測(cè)
三、面試相關(guān)
來(lái)來(lái)來(lái),剛好抽時(shí)間一起整理一下常見(jiàn)面試問(wèn)題吧,然后相關(guān)解析已經(jīng)附上詳細(xì)代碼學(xué)習(xí),實(shí)踐實(shí)踐再實(shí)踐!
1.枚舉允許繼承類(lèi)嗎?
枚舉類(lèi)使用enum定義后在編譯后默認(rèn)繼承了java.lang.Enum類(lèi),而不是普通的繼承Object類(lèi)。enum聲明類(lèi)繼承了Serializable和Comparable兩個(gè)接口。且采用enum聲明后,該類(lèi)會(huì)被編譯器加上final聲明(同String),故該類(lèi)是無(wú)法繼承的。
所有枚舉類(lèi)都默認(rèn)是Enum類(lèi)的子類(lèi),無(wú)需我們使用extends來(lái)繼承。
2.枚舉允許實(shí)現(xiàn)接口嗎?
枚舉允許實(shí)現(xiàn)接口。因?yàn)槊杜e本身就是一個(gè)類(lèi),類(lèi)是可以實(shí)現(xiàn)多個(gè)接口的。
public interface EnumInterface {
public abstract void print();
}
public enum SizeEnum implements EnumInterface{
BIG,MIDDLE,SMALL;
@Override
public void print() {
System.out.println("繼承接口-重寫(xiě)方法一次");
}
}
3.枚舉可以用等號(hào)比較嗎?
肯定,因?yàn)樵贓num類(lèi)里面,已經(jīng)重寫(xiě)了equals方法,而方法里面比較就是直接使用==,來(lái)比較2個(gè)對(duì)象的。所以,你在外邊直接使用==也是可以的。
4.可以繼承枚舉嗎?
當(dāng)然不能呀,枚舉類(lèi)默認(rèn)繼承了java.lang.Enum類(lèi),一個(gè)類(lèi)怎么能繼承兩個(gè)類(lèi)呢?
5.枚舉可以實(shí)現(xiàn)單例模式嗎?
枚舉本身就是一種對(duì)單例設(shè)計(jì)模式友好的形式,它是實(shí)現(xiàn)單例模式的一種很好的方式。
public class InstanceDemo {
/**
* 構(gòu)造方法私有化
*/
private InstanceDemo(){
}
/**
* 返回實(shí)例
* @return
*/
public static InstanceDemo getInstance() {
return Singleton.INSTANCE.getInstance();
}
/**
* 使用枚舉方法實(shí)現(xiàn)單利模式
*/
private enum Singleton {
INSTANCE;
private InstanceDemo instance;
/**
* JVM保證這個(gè)方法絕對(duì)只調(diào)用一次
*/
Singleton() {
instance = new InstanceDemo();
}
public InstanceDemo getInstance() {
return instance;
}
}
//測(cè)試一下
public static void main(String[] args) {
InstanceDemo one = InstanceDemo.getInstance();
InstanceDemo two = InstanceDemo.getInstance();
System.out.println(one);
System.out.println(two);
System.out.println(one == two);
}
}
創(chuàng)建的對(duì)象相同
csdn.test.recursion.demo.InstanceDemo@74a14482
csdn.test.recursion.demo.InstanceDemo@74a14482
true
6.當(dāng)使用compareTo()比較枚舉時(shí),比較的是什么?
int compareTo(E e):比較兩個(gè)枚舉常量誰(shuí)大誰(shuí)小,其實(shí)比較的就是枚舉常量在枚舉類(lèi)中聲明的順序;返回值可以仔細(xì)看看源碼;
一起看看,底層代碼吧
public final int compareTo(E o) {
Enum<?> other = (Enum<?>)o;
Enum<E> self = this;
if (self.getClass() != other.getClass() && // optimization
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;
}
舉個(gè)例子你就能理解了
public class TestSeasonEnum {
public static void main(String[] args) {
Season season = Season.SPRING;
Season season1 = Season.SUMMER;
Season season2 = Season.AUTUMN;
Season season3 = Season.WINTER;
System.out.println(season.compareTo(season1));
System.out.println(season.compareTo(season2));
System.out.println(season.compareTo(season3));
}
}
輸出結(jié)課,詳情參考源碼一看便知道
-1
-2
-3
7. 當(dāng)使用equals()比較枚舉的時(shí)候,比較的是什么?
枚舉類(lèi)型的equals()方法比較的是枚舉類(lèi)對(duì)象的內(nèi)存地址,作用與等號(hào)等價(jià)。
以上就是關(guān)于Java枚舉的相關(guān)內(nèi)容,如果你還想要了解和學(xué)習(xí)更多相關(guān)Java枚舉的應(yīng)用或者其他Java相關(guān)基礎(chǔ)知識(shí)的內(nèi)容,請(qǐng)多多關(guān)注W3Cschool相關(guān)內(nèi)容的文章。