1. java中枚舉怎麼遍歷
我們可以通過反射, 以及枚舉類的靜態方法values()來進行遍歷:
代碼:
enum Rating {
UNRATED, G, PG, PG13, R, NC17
}
public class Test {
public static void main(String args[]) {
System.out.println("第一種通過反射");
Class clz = Rating.class;
for (Object obj: clz.getEnumConstants()) {
System.out.println(obj);
}
System.out.println("第二種通過枚舉靜態方法values()");
for (Rating rate: Rating.values()) {
System.out.println(rate);
}
}
}
運行結果:
第一種通過反射
UNRATED
G
PG
PG13
R
NC17
第二種通過枚舉靜態方法values()
UNRATED
G
PG
PG13
R
NC17
2. java 枚舉類 靜態昏了!
SPRING不是一個新類,它是SeasonEnum的一個實例。你的定義裡面Season有且只有4個對象(不可能再實例化出新的了)就是SPRING,SUMMER,FALL,WINTER。
將print方法改為:
public void print(){
System.out.println(this.getClass());
}
列印出來的肯定是class xxx.xxx.SeasonEnum。
可以按照你下面寫的Season類來「理解」Enum。Enum其實就是一個不能動態實例化新對象的類。
你下面寫的Season類通過反射可以調用private構造方法來實例化對象,但是Enum定義完畢後就絕對不可能再實例化出新對象(除了你已經定義好的如SPRING、SUMMER)。
另外:不是把SPRING,SUMMER,FALL,WINTER"當成"SeasonEnum的實例,它們本來就是SeasonEnum的實例。
3. 為什麼java中用枚舉實現單例模式會更好
枚舉本身就是單例模式。 避免了反射和反序列化的漏洞。 調用的效率比較高,線程安全,實現簡單。 唯一的缺點是沒有實現延時載入。
4. Java中什麼是對象什麼是引用還有枚舉,求大佬解決最好用表達式。
如果你是初學者,我用最好理解的方式跟你說.
對象:就是一個名詞而已,沒啥特別的,學過C語言么?學過C語言的話,結構體,就是對象.
如果沒學過C,我再找一個方式給你說.不過要說對象,得先說類.
在JAVA中,有一種數據結構,
Classstudent{
Stringname;
voidshowname(){
System.Out.print(this.name)
}
}
這就是這種數據結構,JDK也會提供很多,系統給你寫好的,這個是我程序員自己寫的學生類,我們定義了一種學生類,我覺得學生應該有名字屬性,還應該有一個讓別人知道他名字的能力,所以,他有了名字,有了說出名字的能力,都是我寫的,你覺得學生還應該有性別,你就加進去,別賦值.因為學生應該有性別,但不該固定死,你說學生就該是男的么?或者就該是女的?不可能,所以你可以說學生有性別這個屬性,但是他到底是什麼,我不知道,所以你定義類,不能賦值.
那這是我覺得學生類,所有學生都該這樣.
而類跟個體有什麼區別呢?這就像你和人類的關系,類有大的方向性的東西,只有個體有具體的特色.
那麼個體怎麼展現他的特性呢?
還拿這個Student類來說,這個類是大方向,代表所有學生都有名字和說出名字的能力,但具體個體,比如你叫張偉,
那麼
Studentzhangwei=newStudent("zhangwei");
就是通過new關鍵字,從學生類,創建出來一個真真實實的叫張偉的個體.
那麼這個張偉就是對象,所有由new關鍵字,從類中創建的個體就叫對象.
現在明白什麼叫對象了么?
下面說引用,如果你是一個初學者,我希望你只聽我說的第一部分.
int number=123;
這就是一個引用,你這條代碼,執行後,會在存儲空間開辟一個小單元,裡面放著123這個實際數據.
那麼你想使用這個數據,怎麼辦呢?你不知道這個小單元的位置啊,怎麼用呢?Java和所有編程語言都如此,會給你提供一種方案,那就是,給這個單元起個名字,這個單元就叫number,以後你代碼中再寫number,我知道去哪個小單元找數據.
而這個number就是在123這個數據單元的引用.或者number引用123這個單元,說起來,中文有點繞,你怎麼說好像都對,反正你明白這個意思就行.就是一個東西等價另一個東西,這就是一個隊另一個的引用.
這是第一部分,如果你是初學者,聽到這里就可以了,如果你是想鑽研深度的,下面的繼續,
Java中有四種引用,分別為強引用,軟引用,弱引用,虛引用.我再強調一遍啊,如果你是新手,別看這部分.容易讓你亂.
強引用::::::說起來也容易理解,強引用,就是我剛才寫的int number=123這個代碼,這就是強引用,我寫了這代碼,虛擬機運行時,發現,卧槽,內存不夠了啊,這可怎麼辦?要不,我偷偷的,不給你分配內存存儲123?也不告訴你?不行!!!虛擬機如果發現內存不夠了,就會停止運行,告訴你報錯了,內存不夠.因為你寫的這個代碼叫強引用型,特點就是必須要引用成功.
軟引用::::那麼這是什麼,這也是一種引用類型,目的就是,告訴虛擬機,啊,你運行吧,我要創建int number=123,但是,我允許你在出現內存不足時,釋放123這個空間,不用擔心我不讓,我同意了,你可以在內存不足時刪掉我.
這就是軟引用,那具體怎麼實現呢?
intnumber=123;
SoftReferenceruanyinyong=newSoftReference(number);
number=null;
ruanyinyong=get();
這段代碼就是在創建一個軟引用,首先第一行肯定是一個硬引用,就是,無論你內存夠不夠,你必須給我創建數據.
第二行通過系統提供的創建軟引用的類,來為你創建一個軟引用,就是將number等價的存到ruanyinyong這個變數中.
第三行,釋放number這個硬引用為弱引用(後面說),就是告訴系統,number現在不是硬引用了,你可以刪除我了.但是,不幸的是,number在第二行已經重新扔給了ruanyinyong.
現在ruanyingyong就出現了.懂么?
弱引用:::::下面是弱引用,弱引用在剛才說了一嘴,什麼是弱引用呢?弱引用就是比軟引用還低級的引用方式,軟引用是內存不足,才會刪除,弱引用是內存不管你足不足,我虛擬機垃圾回收器只要在周期性掃描垃圾的時候發現你小子了,你就給我玩蛋去.
怎麼達成弱引用呢?那就是使用number=null這種方式,來釋放內存,其實這就是弱引用了,你必須通過=null的方式來告訴虛擬機,這個數據沒用了.但是注意,虛擬機的垃圾回收期是周期性掃描的,也就是說,你雖然寫了=null,但是他不一定立刻刪除,需要掃描到你的時候,才會刪除.但是,你還要注意一點,那就是,雖然還沒刪除,但是引用已經斷開了,人家沒刪除指的是具體數據單元的數據123沒刪除,而不是說你這個引用number沒刪除,其實即使你的123沒刪除,但是number的引用的那根線已經切斷了,你也無法通過number去引用了.
虛引用::::唉呀媽呀,你這也沒個懸賞,我可是一個字一個字給你手寫的,就看你愛學,喜歡認真研究的人,才給你寫的,你要不好好看,多對不起啊.
虛引用我不是很清楚,這個你自己網路下吧,我也查過了,不是很看的懂,所以沒法用自己的語言給你解釋了.
最後最後最後,你的枚舉是吧.
枚舉,我還真把JAVA源代碼給反編譯成匯編看過,枚舉其實就是一個Class類,特殊的類.
你反編譯,看代碼,發現它也是類,可是為啥特殊呢?
這個沒法有通俗易懂的語言,我也沒法按你是新手或者老手不同解釋,這就一個解釋,不懂,你就去看明白啥是類就行了.
我給你描述一個類:
構造器是私有化的,類中的屬性只有get方法,沒有set 方法,而且所有屬性都是靜態的最終的,這樣子的類,就是枚舉類型.
為啥呢?因為枚舉嘛,本意就是不想讓你再創建新的對象,只讓你使用他枚舉列表裡提供的常量,那麼私有化構造器,你就無法使用new調用構造器去創建新對象了.而保證成員屬性不可變,那就是不提供set方法,只有get方法.而屬性是最終的finall類型的,也進一步禁止你修改屬性.
所以你只能用他提供的,不能自己去構造,修改任何數據.這就是枚舉.
這個類其實就是枚舉了.但是這個我們寫出來的模仿出來的枚舉,跟真正的枚舉類是差不多的,只差一點,我們寫的這個,可以通過反射的形式,創建對象,而我們當初設計枚舉時,可一定一定一定不允許用戶創建新的或者修改數據啊,你只能用,不能創建啊!那怎麼辦?沒事,你自己模仿的枚舉不行,我系統提供一個,枚舉類,連反射都無法創建對象,看你怎麼辦?所以我們寫的,跟系統提供的區別僅在於,我們的通過常規手段創建不了,但是反射能創建,而系統提供的,反射都無法創建對象.
那麼你會發現,卧槽,這個特性很符合我們26中設計模式中的"單例模式"的需求啊,設計單利模式不也是需要私有化構造器,然後提供一個不可變的,靜態的對象么?這個算是擴展,你了解單例模式,再說,其實現實中就有很多人用枚舉來完成單例模式,代碼更優雅,更安全,更美觀,我就這么干....