定義: |
---|
Java中的標記接口是一個空接口,沒有任何方法,字段或常量。 有時也稱為標記接口。 |
那么為什么使用Marker接口呢?
有效的問題! 它沒有解決與定義實現該接口的類的協定的接口的目的。 這些接口定義了沒有實現的方法,因為它們告訴子類需要做什么,但是由子類決定如何實現此方法。 但是,在Marker接口的情況下,沒有成員。
標記接口是一種聲明有關類的元數據的方法。 它告訴JVM,需要以不同的方式對實現標記器接口的類的對象進行特殊處理。 Java API中定義了一些現成的Marker接口:
java.io.Serializable
java.lang.Cloneable java.util.RandomAccess java.util.EventListener 我們還可以像創建其他接口一樣創建自己的標記接口版本。
讓我們更深入地了解Cloneable接口。 當需要在Java中克隆對象時,我們使用Object的clone()方法。 但是請注意,此方法不是Cloneable接口的一部分,即,當您的類默認實現Cloneable接口時,將不會像其他任何標準接口一樣實現clone方法。 當我們顯式定義它或調用對象的clone方法時,就可以完成此操作。
因此,不可能僅憑借對象實現此接口的事實來克隆對象。 即使克隆方法是反射式調用的,也不能保證它會成功。
public Object clone() {Object clone = null;try {clone = super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return clone;
}
這里的一個關鍵點是,當您嘗試使用clone()方法克隆對象時,除非實現Cloneable接口,否則將獲得CloneNotSupportedException 。 JVM非常聰明–是嗎?
注意事項:
如前所述,除了使用內置的標記接口之外,我們還可以創建特定于應用程序的標記接口,因為這是標記和邏輯分類代碼的一種好方法。 這在嘗試創建框架或開發API時主要有用。
有趣的一點:
Runnable不是Marker接口。 盡管run是對JVM啟動方法的特殊指令,但是Runnable不是標記接口,因為Runnable內部具有公共的void run()方法。
標記界面存在問題:
標記接口的主要問題是接口定義了用于實現類的協定,并且該協定被所有子類繼承。 這意味著您不能取消實施標記。 如果創建不想序列化的子類(可能是因為它依賴于瞬時狀態),則必須訴諸顯式拋出NotSerializableException .
現在讓我們回到重點。 使用注釋比標記界面更好嗎?
為了回答這個問題,讓我們更詳細地研究Java注釋。
定義: |
---|
Java注釋是Java 1.5中引入的語法元數據(關于數據的數據)的特殊形式。 像Java類一樣,接口甚至注釋都可以在多個Java元素上使用。 |
標記界面與標記注釋
與Javadocs不同,Annotations具有更多功能,可幫助在運行時進行處理。 注釋用于程序包或類聲明,方法聲明,字段聲明和變量聲明中。 它減少了編碼工作,讓開發人員可以輕松開發,專注于業務邏輯,從而提高了自動化程度。
注釋與標準Java元素之間用“ @”符號分隔。 每當編譯器遇到帶有任何Java元素的這些注釋時,它都會從注釋中提取信息并自動生成代碼。
注釋的用途:
- 將信息傳遞給編譯器–用于檢測錯誤或抑制警告。 例如@ SuppressWarnings,@不建議使用
- 編譯時間和部署時間處理–幾種工具可以處理注釋信息以生成代碼XML文件等。諸如Spring,Hibernate之類的框架大量使用注釋。
- 運行時處理–僅在運行時處理這些批注。
以標記接口的類似方式,我們也有標記注釋。 標記注釋沒有任何方法或元素。 該行為與Marker接口相同。
例如, @ Override是內置的Java Marker批注類型,可以將其實現為方法,以指示編譯器編譯器該方法將覆蓋超類中的方法。 它不包含任何其他程序元素。 如果您在不覆蓋超類方法的方法上使用此批注,則編譯器將發出編譯錯誤,以提醒您該事實。 這種注釋類型可以防止程序員在重寫方法時犯錯誤,因為開發人員很可能實際上會在超類中重載方法而不是重寫。
似乎批注比標記界面更好,因為批注可以達到相同的效果。
- 它可以標記變量,方法和/或類。
- 它可以專門標記任何類,也可以通過繼承標記。 標記接口將標記已標記類的所有子類。 例如,如果我們必須將一個類標記為不可序列化,則必須專門將其標記為瞬態。 這可能是值得商bat的,因為注釋不是不可子類化的,可能是優點還是缺點。 注釋默認情況下不會繼承– isAnnotationPresent()會告訴您該特定類上是否存在該注釋,而不是它是否存在于超類或超接口上。 因此,如果您作為批注旨在提供的特殊功能的實現者,希望批注的行為像繼承一樣,則不僅要檢查此類 ,還要檢查每個超類和每個超接口的isAnnotationPresent() 。
- 您可以將數據添加到標記中。 換句話說,非空白的注釋具有價值,因為您所標記的不僅僅是類型。
因此,他們每個人都有一定的優點和缺點,我個人認為應該由開發人員來決定是否使用標記界面或標記注釋,因為他們必須決定考慮實際情況并判斷優點和缺點。他們兩個,并確定最適合該要求的。
參考: 是否有更好的Marker方法? 從我們的JCG合作伙伴 Mainak Goswami在Idiotechie博客上獲得。
標記 2012-10-30
翻譯自: https://www.javacodegeeks.com/2012/10/is-there-a-better-approach-to-marker.html