亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

深入理解Java高級特性——注解

2024-07-14 08:43:37
字體:
來源:轉載
供稿:網友

博主在初學注解的時候看到網上的介紹大部分都是直接介紹用法或者功能,沒有實際的應用場景,篇幅又很長導致學習的時候難以理解其意圖,而且學完就忘QAQ。本篇文章中我將結合實際的應用場景盡可能由淺入深,平緩的介紹java注解。

java注解是jdk1.5以后新出的特性,對于它的應用非常廣泛,我們首先來看一下注解的應用,百度百科上這樣說:

Java,高級特性,注解

我們可以看到,注解的作用有三方面:

編寫doc文檔:這個就我們很常用的 @return 以及 @author,加了這些注解以后,就可以用jdk幫我們自動生成對應的API文檔了

編譯檢查:這個也很常見 @Override,而且功能很強大,我將會在以后的文章中介紹

進行代碼分析:這是本篇文章的重點。這個和編譯檢查一樣也是一個強大的功能,但相比與編譯檢查由于其用到了反射,在性能上存在一些問題

后臺開發中的SSH三大框架,以及咱們安卓端的retrofit,ButterKnife,Lombok等框架和插件也是大量的用到了注解。這里我將通過手擼一個假的ButterKnife來具體演示注解有什么用,怎么用。

我們首先來看段代碼

public class MainActivity extends AppCompatActivity {@OnClick(R.id.test_btn)void test(){ test_tv.setText("恭喜您,綁定成功了!");}@FindViewByID(R.id.test_tv)TextView test_tv;@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bindView(this);}}

這是一個最基本的activity,里面有2個控件,Button和TextView

Java,高級特性,注解

在我點擊Button后TextView的文字被改變。而我所做的僅僅是ButterKnife.bindView(this)并添加2個注解而已,這樣就實現了控件的綁定,省去了很多與業務無關的代碼,是不是簡潔了很多。

看了注解的功能是不是很想了解它是怎么做到的,接下來我就來看看它是什么,怎么用,怎么利用

什么是注解

官方把它叫做元數據,即一種描述數據的數據。所以,可以說注解就是源代碼的元數據。用它來可以來描述、標記我們的源代碼。

怎樣定義一個注解

以下是我上文中定義的一個 @OnClick注解

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface OnClick {int value() default 0;}

可見和定義一個類一樣,只是將class改為 @interface,并且頂部通過幾個原注解來說明這個注解的一些重要信息,具體如下:

J2SE5.0版本在 java.lang.annotation提供了四種元注解,專門注解其他的注解:

  1. @Documented –注解是否將包含在JavaDoc中
  2. @Retention –什么時候使用該注解
  3. @Target? –注解用于什么地方
  4. @Inherited – 是否允許子類繼承該注解

@Documented–一個簡單的Annotations標記注解,表示是否將注解信息添加在java文檔中,一般不用管。

@Retention– 定義該注解的生命周期,很重要,必須指定,以下是3種生命周期的介紹

  1. RetentionPolicy.SOURCE – 在編譯階段丟棄。這些注解在編譯結束之后就不再有任何意義,所以它們不會寫入字節碼。@Override, @SuppressWarnings都屬于這類注解。
  2. RetentionPolicy.CLASS – 在類加載的時候丟棄。在字節碼文件的處理中有用。注解默認使用這種方式。
  3. RetentionPolicy.RUNTIME– 始終不會丟棄,運行期也保留該注解,因此可以使用反射機制讀取該注解的信息。我們自定義的注解通常使用這種方式。

@Target – 表示該注解用于什么地方。如果不明確指出,該注解可以放在任何地方。以下是一些可用的參數。需要說明的是:屬性的注解是兼容的,如果你想給7個屬性都添加注解,僅僅排除一個屬性,那么你需要在定義target包含所有的屬性。

ElementType.TYPE:用于描述類、接口或enum聲明
ElementType.FIELD:用于描述實例變量
ElementType.METHOD
ElementType.PARAMETER
ElementType.CONSTRUCTOR
ElementType.LOCAL_VARIABLE
ElementType.ANNOTATION_TYPE 另一個注釋
ElementType.PACKAGE 用于記錄java文件的package信息

@Inherited – 定義該注釋和子類的關系

那么注解體里的內容有該怎樣定義

Annotations只支持基本類型、String及枚舉類型。注釋中所有的屬性被定義成方法,并允許提供默認值。

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@interface Book{public enum Priority {LOW, MEDIUM, HIGH}String author() default "Yash";int price() default 20;Status status() default Status.NOT_STARTED;}

看看怎么用它

@Todo(priority = Todo.Priority.MEDIUM, author = "zsq", status = Todo.Status.STARTED)public void incompleteMethod1() {}

通過字段名 = 的形式給字段賦值,如果沒賦值,則使用缺省值。如果注解中只有一個屬性,可以直接命名為“value”,使用時無需再標明屬性名,例如我定義的 @OnClick注解。

好了,花了那么多精力來認識他,該看看該怎么來利用它了

我們定義了自己的注解并將其應用在業務邏輯的方法上?,F在我們需要寫一個用戶程序調用我們的注解。這里我們需要使用反射機制。如果你熟悉反射代碼,就會知道反射可以提供類名、方法和實例變量對象。所有這些對象都有getAnnotation()這個方法用來返回注解信息。我們需要把這個對象轉換為我們自定義的注釋(使用 instanceOf()檢查之后),同時也可以調用自定義注釋里面的方法。

所有這些對象都有getAnnotation()!

所有這些對象都有getAnnotation()!

所有這些對象都有getAnnotation()!

重要的API說3遍,另外用到的幾個方法也很重要,下面的代碼會演示,更多的API使用參考可以去查閱JDK文檔。

具體到我們本編文章的實例,調用注解的家伙就是我們剛剛在MainActivity里用到的 ButterKnife,我們通過設置監聽的注解來看看它到底做了什么

public static final void bindView(final Activity activity){ traversalMethod(activity); traversalField(activity);}

在我們調用的ButterKnife.bindView(this)中我們拿到了MainActivity的實例,并且通過反射遍歷里面所有的方法:

private static void traversalMethod(final Activity activity) { Method[] methodArray = getObjectMethodArray(activity); for (final Method method:methodArray){  if(isAnnotationPresent(method)){   int viewID = getViewID(method);   setOnClickListenerForControl(activity, method, viewID);  } }}private static Method[] getObjectMethodArray(Activity activity) { return activity.getClass().getMethods();}

接著判斷方法是否被我們注解:

private static boolean isAnnotationPresent(Method method) { return method.isAnnotationPresent(OnClick.class);}

如果是我們用注解標注的方法則通過注解獲取注解里保存的空間ID,并且通過MainActivity的實例為其設置點擊監聽,在監聽內調用被注解標注的方法。

private static int getViewID(Method method) { return method.getAnnotation(OnClick.class).value();}private static void setOnClickListenerForControl(final Activity activity, final Method method, int viewID) { activity.findViewById(viewID).setOnClickListener(new View.OnClickListener() {  @Override  public void onClick(View view) {   try {    method.invoke(activity);   } catch (IllegalAccessException e) {    e.printStackTrace();   } catch (InvocationTargetException e) {    e.printStackTrace();   }  } });}

大功告成!是不是很簡單

我們用反射獲取注解的方式實現了ButterKnife的功能,但文章開頭說過反射的存在性能上的不足。而實際上ButterKnife本身用的也不是反射,而是用的apt工具在編譯時期就可以獲取到所有的方法、字段、以及他們的注解,從而避免了使用反射,解決了性能的問題。接下來的文章我會講解本文開頭提到的第三點,也就是ButterKnife實際使用的方法,將我們自己的ButterKnife改為ButterKnife官方的實現方法。

以上所述是小編給大家介紹的Java高級特性——注解詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久精品成人欧美大片古装| 精品久久香蕉国产线看观看gif| 久久精品国产成人精品| 国产中文欧美精品| 亚洲最大av网站| 91在线视频精品| 国产精品亚洲аv天堂网| 欧美另类在线播放| 国产97在线视频| 欧美大片大片在线播放| 国产精品www色诱视频| 欧美性猛交99久久久久99按摩| 久久久久久久影视| 日韩理论片久久| 国产精品嫩草视频| 国产欧美va欧美va香蕉在| 欧美亚洲免费电影| 深夜成人在线观看| 日韩人体视频一二区| 国产精品男女猛烈高潮激情| 久久国产精品电影| 欧美日韩成人精品| 国产美女精彩久久| 一区二区欧美久久| 538国产精品视频一区二区| 亚洲在线第一页| 91最新国产视频| 亚洲2020天天堂在线观看| 欧美黑人极品猛少妇色xxxxx| 日本中文字幕成人| 91丝袜美腿美女视频网站| 国产在线a不卡| 亚洲深夜福利网站| 欧美成人剧情片在线观看| 久久99久久99精品中文字幕| 色综合亚洲精品激情狠狠| 中文字幕在线亚洲| 日韩中文字幕第一页| 欧美高清在线视频观看不卡| 亚洲情综合五月天| 国产区精品视频| 午夜精品一区二区三区在线播放| 国产成人中文字幕| 欧美精品免费在线观看| 国产精品扒开腿做| 色妞在线综合亚洲欧美| 亚洲精品少妇网址| 欧美韩日一区二区| 欧美久久精品一级黑人c片| 亚洲免费成人av电影| 91高清免费视频| 欧美在线视频网站| 超薄丝袜一区二区| 国产999精品久久久| 在线中文字幕日韩| 国产欧美精品一区二区三区介绍| 国产精品日韩av| 一区二区三区视频免费| 成人av资源在线播放| 欧美视频二区36p| 日韩高清免费观看| 亚洲国产欧美一区二区丝袜黑人| 久久香蕉国产线看观看av| 成人精品久久久| 亚洲综合自拍一区| 欧美精品九九久久| 欧美成人中文字幕在线| 欧美日韩免费在线观看| 韩国三级日本三级少妇99| 91老司机精品视频| 亚洲免费小视频| 国产成人亚洲综合91精品| 欧美激情乱人伦一区| 992tv成人免费影院| 亚洲永久在线观看| 日韩精品亚洲精品| 欧美一级成年大片在线观看| 国产精品亚洲欧美导航| 色青青草原桃花久久综合| 国产精品自产拍高潮在线观看| 91久久在线视频| 欧美国产日韩一区二区在线观看| 国产精品99久久久久久人| 欧美色视频日本版| 91中文在线观看| 久久噜噜噜精品国产亚洲综合| 日韩视频永久免费观看| 国产69久久精品成人看| 亚洲日韩第一页| 欧美成年人视频网站| 日韩成人在线免费观看| 国模极品一区二区三区| 欧美日韩成人黄色| 亚洲人精选亚洲人成在线| 亚洲在线免费看| 91日本视频在线| 亚洲一区二区三区视频| 成人性教育视频在线观看| 国产精品国产三级国产专播精品人| 精品国产91久久久久久老师| 2019最新中文字幕| 精品一区精品二区| 成人免费网站在线观看| 色噜噜亚洲精品中文字幕| 69精品小视频| 亚洲精品网址在线观看| 国产成人在线播放| 国产精品久久久久77777| 久久久久北条麻妃免费看| 在线中文字幕日韩| 黑人巨大精品欧美一区二区免费| 97国产suv精品一区二区62| 久久人人爽人人爽人人片av高请| 欧美午夜性色大片在线观看| 性欧美办公室18xxxxhd| 91精品国产综合久久男男| 国产成人精品最新| 亚洲国产精品久久久久| 日韩麻豆第一页| 亚洲网站在线播放| 国产成人一区二区三区小说| 欧美大片网站在线观看| 中文字幕欧美专区| 最近中文字幕2019免费| 成人免费自拍视频| 亚洲毛茸茸少妇高潮呻吟| 日韩精品免费电影| 日本午夜人人精品| 91精品免费视频| 91精品久久久久久久久久另类| 久久久精品影院| 国产丝袜高跟一区| 久久精品99久久久香蕉| 亚洲精品中文字幕av| 亚洲视频在线免费看| 久久国产精品久久久久久| 日本成人激情视频| 国产精品爱啪在线线免费观看| 亚洲春色另类小说| 久久国产色av| 国产成人中文字幕| 亚洲黄色片网站| 日韩精品福利在线| 欧美国产日韩免费| 少妇av一区二区三区| 精品偷拍一区二区三区在线看| 亚洲国产精品99| 欧美日韩综合视频网址| 国产97在线亚洲| 欧美精品第一页在线播放| 久久久亚洲影院| 久久精品电影网| 81精品国产乱码久久久久久| 日韩精品免费观看| 中文字幕av一区中文字幕天堂| 欧美精品电影在线| 91产国在线观看动作片喷水| 亚洲成人xxx| 亚洲欧美中文在线视频| 午夜精品蜜臀一区二区三区免费| 97视频免费在线看| 欧美小视频在线| 精品久久香蕉国产线看观看亚洲| 国产精品国产自产拍高清av水多|