一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 深入理解Java高級特性——注解

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

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

這篇文章主要介紹了Java高級特性——注解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

博主在初學注解的時候看到網上的介紹大部分都是直接介紹用法或者功能,沒有實際的應用場景,篇幅又很長導致學習的時候難以理解其意圖,而且學完就忘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;

@Override
protected 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高級特性——注解詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!

延伸 · 閱讀

精彩推薦
  • Java教程java 中鎖的性能提高辦法

    java 中鎖的性能提高辦法

    這篇文章主要介紹了java 中鎖的性能提高辦法的相關資料,需要的朋友可以參考下...

    Java之家3092020-08-13
  • Java教程淺談Java(SpringBoot)基于zookeeper的分布式鎖實現

    淺談Java(SpringBoot)基于zookeeper的分布式鎖實現

    這篇文章主要介紹了Java(SpringBoot)基于zookeeper的分布式鎖實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的...

    LJY_SUPER5742021-07-21
  • Java教程JAVA中通過自定義注解進行數據驗證的方法

    JAVA中通過自定義注解進行數據驗證的方法

    java 自定義注解驗證可自己添加所需要的注解,下面這篇文章主要給大家介紹了關于JAVA中通過自定義注解進行數據驗證的相關資料,文中通過示例代碼介紹...

    Decouple6362021-05-25
  • Java教程Java list.remove( )方法注意事項

    Java list.remove( )方法注意事項

    這篇文章主要介紹了Java list.remove( )方法注意事項,非常簡單易懂,需要的朋友可以參考下...

    妖久9552021-05-25
  • Java教程springboot ehcache 配置使用方法代碼詳解

    springboot ehcache 配置使用方法代碼詳解

    EhCache是一個比較成熟的Java緩存框架,Springboot對ehcache的使用非常支持,所以在Springboot中只需做些配置就可使用,且使用方式也簡易,今天給大家分享spri...

    m1719309529412912021-09-16
  • Java教程JavaWeb 實現驗證碼功能(demo)

    JavaWeb 實現驗證碼功能(demo)

    在 WEB-APP 中一般應用于:登錄、注冊、買某票、秒殺等場景,大家都接觸過這個驗證碼操作,今天小編通過實例代碼給大家講解javaweb實現驗證碼功能,需要...

    java教程網12832020-08-05
  • Java教程Java之Springcloud Feign組件詳解

    Java之Springcloud Feign組件詳解

    這篇文章主要介紹了Java之Springcloud Feign組件詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    深情以改10322021-11-12
  • Java教程SpringBoot引入Thymeleaf的實現方法

    SpringBoot引入Thymeleaf的實現方法

    這篇文章主要介紹了SpringBoot引入Thymeleaf的實現方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下...

    Bobby6472021-07-28
主站蜘蛛池模板: 日本xxxxx高清免费观看 | 欧美人禽杂交av片 | 午夜免费小视频 | 久久91精品国产91 | 三星w699 | 久久国产精品福利影集 | 免费在线公开视频 | 精品国产国产精2020久久日 | 久久re视频这里精品一本到99 | xxxxxx日本处大片免费看 | 国产精品欧美在线观看 | 欧美成人第一页 | 玩高中女同桌肉色短丝袜脚文 | 9色视频在线观看 | 日本高清在线精品一区二区三区 | 妹妹你插的我好爽 | 午夜国产小视频 | 日本大片免aaa费观看视频 | 亚洲国产天堂综合一区 | 深夜在线 | 日本搜子同屋的日子2国语 日本爽p大片免费观看 | 无码国产成人午夜在线观看不卡 | 四虎在线网站 | 亚洲免费网站在线观看 | 色婷婷精品 | 精品欧美一区二区三区在线观看 | 久久全国免费观看视频 | 非洲黑女人性xxxx | 4438成人网 | 女人国产香蕉久久精品 | 成年看片免费高清观看 | 成人特级毛片69免费观看 | 高h喷水荡肉爽文np肉色文 | 美女脱了内裤让男桶爽 | 国产成人精品高清在线 | 91精品综合国产在线观看 | 肉文小说 | 无人在线高清免费看 | 国产免费大片 | 美女的让男人桶爽免费看 | 免费观看视频高清在线 |