激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - 深入理解Java高級(jí)特性——注解

深入理解Java高級(jí)特性——注解

2019-06-23 11:45洛基loky Java教程

這篇文章主要介紹了Java高級(jí)特性——注解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

博主在初學(xué)注解的時(shí)候看到網(wǎng)上的介紹大部分都是直接介紹用法或者功能,沒(méi)有實(shí)際的應(yīng)用場(chǎng)景,篇幅又很長(zhǎng)導(dǎo)致學(xué)習(xí)的時(shí)候難以理解其意圖,而且學(xué)完就忘QAQ。本篇文章中我將結(jié)合實(shí)際的應(yīng)用場(chǎng)景盡可能由淺入深,平緩的介紹java注解。

java注解是jdk1.5以后新出的特性,對(duì)于它的應(yīng)用非常廣泛,我們首先來(lái)看一下注解的應(yīng)用,百度百科上這樣說(shuō):

深入理解Java高級(jí)特性——注解

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

編寫(xiě)doc文檔:這個(gè)就我們很常用的 @return 以及 @author,加了這些注解以后,就可以用jdk幫我們自動(dòng)生成對(duì)應(yīng)的API文檔了

編譯檢查:這個(gè)也很常見(jiàn) @Override,而且功能很強(qiáng)大,我將會(huì)在以后的文章中介紹

進(jìn)行代碼分析:這是本篇文章的重點(diǎn)。這個(gè)和編譯檢查一樣也是一個(gè)強(qiáng)大的功能,但相比與編譯檢查由于其用到了反射,在性能上存在一些問(wèn)題

后臺(tái)開(kāi)發(fā)中的SSH三大框架,以及咱們安卓端的retrofit,ButterKnife,Lombok等框架和插件也是大量的用到了注解。這里我將通過(guò)手?jǐn)]一個(gè)假的ButterKnife來(lái)具體演示注解有什么用,怎么用。

我們首先來(lái)看段代碼

public class MainActivity extends AppCompatActivity {

@OnClick(R.id.test_btn)
void test(){
 test_tv.setText("恭喜您,綁定成功了!");
}

@FindViewByID(R.id.test_tv)
TextView test_tv;

@Override
protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 ButterKnife.bindView(this);
}
}

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

深入理解Java高級(jí)特性——注解

在我點(diǎn)擊Button后TextView的文字被改變。而我所做的僅僅是ButterKnife.bindView(this)并添加2個(gè)注解而已,這樣就實(shí)現(xiàn)了控件的綁定,省去了很多與業(yè)務(wù)無(wú)關(guān)的代碼,是不是簡(jiǎn)潔了很多。

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

什么是注解

官方把它叫做元數(shù)據(jù),即一種描述數(shù)據(jù)的數(shù)據(jù)。所以,可以說(shuō)注解就是源代碼的元數(shù)據(jù)。用它來(lái)可以來(lái)描述、標(biāo)記我們的源代碼。

怎樣定義一個(gè)注解

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnClick {

int value() default 0;

}

可見(jiàn)和定義一個(gè)類一樣,只是將class改為 @interface,并且頂部通過(guò)幾個(gè)原注解來(lái)說(shuō)明這個(gè)注解的一些重要信息,具體如下:

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

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

@Documented–一個(gè)簡(jiǎn)單的Annotations標(biāo)記注解,表示是否將注解信息添加在java文檔中,一般不用管。

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

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

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

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

@Inherited – 定義該注釋和子類的關(guān)系

那么注解體里的內(nèi)容有該怎樣定義

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

@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() {

}

通過(guò)字段名 = 的形式給字段賦值,如果沒(méi)賦值,則使用缺省值。如果注解中只有一個(gè)屬性,可以直接命名為“value”,使用時(shí)無(wú)需再標(biāo)明屬性名,例如我定義的 @OnClick注解。

好了,花了那么多精力來(lái)認(rèn)識(shí)他,該看看該怎么來(lái)利用它了

我們定義了自己的注解并將其應(yīng)用在業(yè)務(wù)邏輯的方法上。現(xiàn)在我們需要寫(xiě)一個(gè)用戶程序調(diào)用我們的注解。這里我們需要使用反射機(jī)制。如果你熟悉反射代碼,就會(huì)知道反射可以提供類名、方法和實(shí)例變量對(duì)象。所有這些對(duì)象都有g(shù)etAnnotation()這個(gè)方法用來(lái)返回注解信息。我們需要把這個(gè)對(duì)象轉(zhuǎn)換為我們自定義的注釋(使用 instanceOf()檢查之后),同時(shí)也可以調(diào)用自定義注釋里面的方法。

所有這些對(duì)象都有g(shù)etAnnotation()!

所有這些對(duì)象都有g(shù)etAnnotation()!

所有這些對(duì)象都有g(shù)etAnnotation()!

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

具體到我們本編文章的實(shí)例,調(diào)用注解的家伙就是我們剛剛在MainActivity里用到的 ButterKnife,我們通過(guò)設(shè)置監(jiān)聽(tīng)的注解來(lái)看看它到底做了什么

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

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

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);
}

如果是我們用注解標(biāo)注的方法則通過(guò)注解獲取注解里保存的空間ID,并且通過(guò)MainActivity的實(shí)例為其設(shè)置點(diǎn)擊監(jiān)聽(tīng),在監(jiān)聽(tīng)內(nèi)調(diào)用被注解標(biāo)注的方法。

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();
   }
  }

 });
}

大功告成!是不是很簡(jiǎn)單

我們用反射獲取注解的方式實(shí)現(xiàn)了ButterKnife的功能,但文章開(kāi)頭說(shuō)過(guò)反射的存在性能上的不足。而實(shí)際上ButterKnife本身用的也不是反射,而是用的apt工具在編譯時(shí)期就可以獲取到所有的方法、字段、以及他們的注解,從而避免了使用反射,解決了性能的問(wèn)題。接下來(lái)的文章我會(huì)講解本文開(kāi)頭提到的第三點(diǎn),也就是ButterKnife實(shí)際使用的方法,將我們自己的ButterKnife改為ButterKnife官方的實(shí)現(xiàn)方法。

以上所述是小編給大家介紹的Java高級(jí)特性——注解詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲第一成人在线 | 国产精品视频在线观看免费 | 精品亚洲免费 | 成人在线视频免费播放 | h色在线观看 | 国产一区二区三区影视 | 久久毛片免费 | 92看片淫黄大片一级 | 国产精品久久久久久影院8一贰佰 | 亚洲成人高清在线观看 | 一本一本久久a久久精品综合小说 | 亚洲国产精品久久久久久久久 | 欧美乱码精品一区 | 亚洲欧美在线看 | 999久久久国产999久久久 | 欧美五月婷婷 | 国产一级毛片a | 91网站链接 | 一级做a爱片性色毛片高清 日本一区二区在线看 | 国产亚洲在 | 国产1区在线观看 | 午夜视频观看 | 国产电影精品 | 精品国产96亚洲一区二区三区 | 成年片黄色日本大片网站视频 | 国产成人午夜高潮毛片 | 久久国精品 | 99精品电影| 性大片性大片免费 | 欧洲黄视频 | 欧美久久久一区二区三区 | 日韩在线视频在线观看 | 黄色免费av | 看一级毛片 | 中文在线观看视频 | 嫩草影院在线观看网站成人 | 久久tv免费国产高清 | 永久av在线免费观看 | 久草干| 欧美顶级毛片在线播放小说 | 成品片a免人视频 |