第37條:用標(biāo)記接口定義類型

定義

標(biāo)記接口(marker interface):沒有包含方法聲明的接口屿衅,而只是指明一個類實(shí)現(xiàn)了具有某種屬性的接口杯活。例如裕循,Serializable接口。
標(biāo)記注解(marker annotation):特殊類型的注解颅停,其中不包含成員。標(biāo)記注解的唯一目的就是標(biāo)記聲明掠拳。例如癞揉,@Override。

優(yōu)缺點(diǎn)對比

標(biāo)記接口的優(yōu)點(diǎn):

  • 標(biāo)記接口定義的類型是由北標(biāo)記類的實(shí)例實(shí)現(xiàn)的溺欧;標(biāo)記接口則沒有定義的類型喊熟;
    這個類型允許你在編譯時捕捉在使用標(biāo)記注解的情況下要到運(yùn)行時才能捕捉到的錯誤 .
    比如:就Serializable標(biāo)記接口而言,如果他的參數(shù)沒有實(shí)現(xiàn)該接口姐刁,那么ObjectOutputStream.writeObject(Object, obj)方法將會失敗芥牌。令人不解的是ObjectOutputStream API的創(chuàng)建者在聲明write方法的時候并沒有利用Serializable接口。因此如果將沒有實(shí)現(xiàn)Serializable的對象上調(diào)用ObjectOutputStream.write龙填,只會在運(yùn)行時失敗胳泉。
pic2.jpg
pic1.jpg
  • 標(biāo)記接口可以更加精確的進(jìn)行鎖定。
    如果注解類型利用@Target(ElementType.TYPE)聲明岩遗,它就可以被應(yīng)用到任何類或者接口扇商,假設(shè)有一個標(biāo)記只是適用于特殊的接口實(shí)現(xiàn),但它卻可以被應(yīng)用到類宿礁,如果定義成一個標(biāo)記接口案铺,就可以用它將唯一的接口擴(kuò)展成適用的接口。

Set接口就可以說是這種有限制的標(biāo)記接口梆靖。他只是用與Collection子類型控汉,但是他不會添加除了Collection定義之外的方法。一般情況下返吻,不把它當(dāng)作標(biāo)記接口姑子,因?yàn)樗倪M(jìn)了幾個Collection的方法的契約,比如add测僵、equals和hashCode街佑。但是很容易想象只適用于某種特殊接口的子類型的標(biāo)記接口,他沒有改進(jìn)接口的任何方法的契約捍靠。這種標(biāo)記接口可以描述整個對象的某個約束條件沐旨,或者表明實(shí)例能夠利用其他某個類的方法進(jìn)行處理(就像Serializable接口表明實(shí)例可以通過ObjectOutputStream進(jìn)行處理一樣)。

聲明set注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Set {

}
@Set
public class HashSet {
}

set接口:

public interface Set<E> extends Collection<E> {
    // Query Operations
/** @param e element to be added to this set
     * @return <tt>true</tt> if this set did not already contain the specified
     *         element
     * @throws UnsupportedOperationException if the <tt>add</tt> operation
     *         is not supported by this set
     * @throws ClassCastException if the class of the specified element
     *         prevents it from being added to this set
     * @throws NullPointerException if the specified element is null and this
     *         set does not permit null elements
     * @throws IllegalArgumentException if some property of the specified element
     *         prevents it from being added to this set
     */
    boolean add(E e);
}
public interface Collection<E> extends Iterable<E> {
/** @param e element whose presence in this collection is to be ensured
     * @return <tt>true</tt> if this collection changed as a result of the
     *         call
     * @throws UnsupportedOperationException if the <tt>add</tt> operation
     *         is not supported by this collection
     * @throws ClassCastException if the class of the specified element
     *         prevents it from being added to this collection
     * @throws NullPointerException if the specified element is null and this
     *         collection does not permit null elements
     * @throws IllegalArgumentException if some property of the element
     *         prevents it from being added to this collection
     * @throws IllegalStateException if the element cannot be added at this
     *         time due to insertion restrictions
     */
    boolean add(E e);
}

標(biāo)記注解的優(yōu)點(diǎn)

  • 標(biāo)記注解可以通過默認(rèn)的方式添加一個或者多個注解類型元素 , 給已被實(shí)用的注解類型添加更多地信息 榨婆。隨著時間的推移磁携,簡單的編輯注解類型可以演變成更加豐富的注解類型。這種演變對于編輯接口而言則是不可能的良风,因?yàn)樗ǔ2豢赡茉趯?shí)現(xiàn)接口之后再給他添加方法谊迄。
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
 * Created by Jiang Meiwei on 2017/6/27.
 */

@Retention(RUNTIME)
@Target(ElementType.METHOD)
public @interface ExceptinTest{
Class<? extends Exception> value();
}
package com.thunisoft.yilian.lafx.server.ajsc;

/**
 * Created by Jiang Meiwei on 2017/6/28.
 */
public class Sample {
    
    @ExceptinTest(ArithmeticException.class)
    public static void m1(){
        int i = 0;
        i = i/i;
    }
    @ExceptinTest(ArithmeticException.class)
    public static void m2(){
        int[] a = new int[0];
        int i = a[1];
    }

    @ExceptinTest(ArithmeticException.class)
    public static void m3(){
    }
}
package com.thunisoft.yilian.lafx.server.ajsc;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Created by Jiang Meiwei on 2017/6/28.
 */
public class RunTests {
    public static void main(String[] args) throws ClassNotFoundException{
        int tests = 0;
        int passed = 0;
        Class testClass = Class.forName("com.thunisoft.yilian.lafx.server.ajsc.Sample");
        for (Method m: testClass.getDeclaredMethods()) {
            if(m.isAnnotationPresent(ExceptinTest.class)){
                tests++;
                try {
                    m.invoke(null);
                }catch (InvocationTargetException wrappedEx) {
                    Throwable exc = wrappedEx.getCause();
                    Class<? extends Exception> excType = m.getAnnotation(ExceptinTest.class).value();
                    if(excType.isInstance(exc)){
                        passed++;
                    } else {
                        System.out.printf("Test %s failed: exppected %s, got %s%n", m, excType.getName(), exc);
                        
                    }
                } catch(Exception exc){
                    System.out.printf("Test %s failed: on exception%n", m);
                }
            }
        }

    }
}

輸出結(jié)果:

pic3.jpg

做了如下更改:

pic4.jpg
  • 標(biāo)記注解是更大注解機(jī)制的一部分 , 這意味這它在那些支持注解作為編程元素之一的框架中同樣具有一致性

標(biāo)記注解和標(biāo)記接口的選擇

  • 如果標(biāo)記是應(yīng)用到程序元素而不是類或者接口闷供,就必須用注解;
  • 如果標(biāo)記只應(yīng)用給類和接口鳞上,那么就標(biāo)記接口優(yōu)先于標(biāo)記注解这吻;
  • 如果要定義一個任何新方法都不會與之關(guān)聯(lián)的類型,標(biāo)記接口是最好的選擇篙议;
  • 如果想要標(biāo)記程序元素而非類和接口唾糯,考慮到未來可能要給標(biāo)記添加更多的信息忙活著標(biāo)記更適合于已經(jīng)廣泛使用了注解類型的框架,那么就該使用標(biāo)記注解鬼贱。

總結(jié):從某種意義上說移怯,本條目與第19條中“如果不想定義類型就不要使用接口”的說法相反。本條目接近的意思是說:如果想要定義類型这难,一定要使用接口舟误。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市姻乓,隨后出現(xiàn)的幾起案子嵌溢,更是在濱河造成了極大的恐慌,老刑警劉巖蹋岩,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赖草,死亡現(xiàn)場離奇詭異,居然都是意外死亡剪个,警方通過查閱死者的電腦和手機(jī)秧骑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扣囊,“玉大人乎折,你說我怎么就攤上這事∏中” “怎么了骂澄?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長惕虑。 經(jīng)常有香客問我酗洒,道長,這世上最難降的妖魔是什么枷遂? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮棋嘲,結(jié)果婚禮上酒唉,老公的妹妹穿的比我還像新娘。我一直安慰自己沸移,他們只是感情好痪伦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布侄榴。 她就那樣靜靜地躺著,像睡著了一般网沾。 火紅的嫁衣襯著肌膚如雪癞蚕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天辉哥,我揣著相機(jī)與錄音桦山,去河邊找鬼。 笑死醋旦,一個胖子當(dāng)著我的面吹牛恒水,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播饲齐,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼钉凌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捂人?” 一聲冷哼從身側(cè)響起御雕,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滥搭,沒想到半個月后酸纲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡论熙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年福青,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脓诡。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡无午,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出祝谚,到底是詐尸還是另有隱情宪迟,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布交惯,位于F島的核電站次泽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏席爽。R本人自食惡果不足惜意荤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望只锻。 院中可真熱鬧玖像,春花似錦、人聲如沸齐饮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至握恳,卻和暖如春瞒窒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背乡洼。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工崇裁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人就珠。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓寇壳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親妻怎。 傳聞我的和親對象是個殘疾皇子壳炎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • JAVA序列化機(jī)制的深入研究 對象序列化的最主要的用處就是在傳遞,和保存對象(object)的時候,保證對象的完整...
    時待吾閱讀 10,868評論 0 24
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)逼侦,斷路器匿辩,智...
    卡卡羅2017閱讀 134,667評論 18 139
  • 在經(jīng)過一次沒有準(zhǔn)備的面試后,發(fā)現(xiàn)自己雖然寫了兩年的android代碼榛丢,基礎(chǔ)知識卻忘的差不多了铲球。這是程序員的大忌,沒...
    猿來如癡閱讀 2,843評論 3 10
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,823評論 6 342
  • 可能某一天你會在某個地方遇見一個像我一樣的人晰赞,她有著和我一樣的眉眼稼病,一樣的長發(fā),一樣的微笑掖鱼。只是她再也不像我那樣愛你然走。
    愛你不烈不弱閱讀 144評論 0 0