Java註解的簡單說明__Java

來源:互聯網
上載者:User
Java5開始,Java開始對中繼資料的支援,也就是annotation(註解/標籤)
中繼資料:metadata:描述資料的資料:

所有的Annotation都是java.lang.annotation.Annotation介面的子介面,所以Annotation是一種特殊的介面(枚舉也是特殊的類)
枚舉:所有的枚舉類型都是java.lang.Enum類的子類。--->枚舉是一種特殊的類。
註解:所有的註解都是java.lang.annotation.Annotation介面的子介面,註解是一種特殊的介面。

使用註解:
注意:註解本身不具有任何功能,得提供第三方的程式來賦予它功能

使用註解有三方程式參與:
1、首先必須存在一個註解類;
2、其次必須存在被貼的程式元素;
3、必須有第三方的程式來賦予註解特殊的功能(反射操作)。

在Java中,內建有5個註解:(Java5出現3個,Java7出現1個,Java8出現1個):
@Override                                限定子類是否覆寫父類方法
@Deprecated                           標記已淘汰,過時的方法/類不推薦使用
@SuppressWarings                  抑制編譯器發出的警告,僅僅是抑制警告,問題依然存在
@SuppressWarings(value="all")
@safeVarargs                           抑制堆汙染警告(Java7開始出現的)
@FunctionalInterface               Java8出現,表示函數式介面,只允許該介面中只有一個抽象方法。如果一個介面中就只有一個抽象方法,也可以不使用註解。可以運用函數式編程(lambda文法)。

Java5才開始出現註解,才開始有@Deprecated註解,但是java.util.Date類中在JDK1.1的時候很多方法就過時了:
在Java5之前標記某一個方法過時,使用文檔注釋。

/** * Created by Layne_Yao on 2017-8-5 上午9:51:42. * CSDN:http://blog.csdn.net/Jsagacity */public class AnnotationDemo {//從Java5開始@Deprecatedpublic void annotation1() {}//在Java5之前/** * @deprecated */public void annotation2() {}public static void main(String[] args) {}}


註解:用來貼在類,方法,構造器,欄位,參數等之上,用於給被貼的程式元素賦予一定的功能。
元註解:在註解定義的時候,必須使用元註解來標註,元註解的註解。

@Retention:決定了註解可以保持在哪一個時期,一共三個時期,都封裝在RetentionPolicy枚舉類中:
       SOURCE:該註解在編譯時間期就會丟棄,不會存在於位元組碼檔案中,只能存在於源檔案中;
       CLASS:該註解可以存在源檔案和位元組碼檔案中,但是一旦載入進JVM,就丟失;
       RUNTIME:該註解可以存在源檔案,位元組碼,JVM中。
自訂的註解類,都是要RUNTIME,因為我們需要在運行時期通過反射賦予註解特殊功能。

@Target:決定了註解可以貼在哪些成員元素之上。可以貼的成員元素都很多,都封裝在ElementType枚舉類中。
          ElementType.ANNOTATION_TYPE 只能修飾注釋型別宣告 
          ElementType.CONSTRUCTOR       只能修飾構造方法聲明 
          ElementType.FIELD                        只能修飾欄位聲明(包括枚舉常量) 
          ElementType.LOCAL_VARIABLE    只能修飾局部變數聲明 
          ElementType.METHOD                  只能修飾方法聲明 
          ElementType.PACKAGE                 只能修飾包聲明 
          ElementType.PARAMETER            只能修飾參數聲明 
          ElementType.TYPE                       只能修飾類、介面(包括注釋類型)或枚舉聲明 

@Documentd:使用@Documentd標註的標籤會儲存字API文檔中。
@Inherited:@Inherited標註的標籤可以被子類所繼承。



在Class,Method,Field,Constructor中有擷取/判斷註解存在的方法
常用的API:
Annotation getAnnotation(Class annotationClass):判斷當前類、方法、欄位上是否擁有指定的註解,若有,則返回當前對象,若沒有返回null;

Annotation[] getAnnotations():返回此元素上存在的所有注釋。

boolean isAnnotationPresent(Class annotationClass):如果指定類型的注釋存在於此元素上,則返回 true,否則返回 false。 

註解類:

//定義註解@Target(ElementType.TYPE)//只能修飾類、介面(包括注釋類型)或枚舉聲明 @Retention(RetentionPolicy.RUNTIME)//該註解可以存在源檔案,位元組碼,JVM中。public @interface INFO {//註解是特殊的介面,介面中有抽象方法,在註解八抽象方法稱為屬性String username();int age() default 20;//default是設定預設值String[] hobby();Gender sex() default Gender.NONE;}

Gender需要設定成public:

/** * Created by Layne_Yao on 2017-8-5 上午11:11:03. * CSDN:http://blog.csdn.net/Jsagacity */public enum Gender{BOY,GIRL,NONE;}

賦予特殊功能得類:

/** * Created by Layne_Yao on 2017-8-5 上午9:51:42. * CSDN:http://blog.csdn.net/Jsagacity */// 被貼程式元素@INFO(username = "Layne", age = 18, sex = Gender.BOY, hobby = { "Java","Android", "C++" })class User {@Deprecatedpublic void doWork() {}}// 賦予註解特殊功能得public class AnnotationDemo1 {public static void main(String[] args) throws Exception {// 擷取Person類上的VIP註解中的資訊Class cls = User.class;// 擷取Person類上所有的註解Annotation[] as = cls.getAnnotations();// 判斷Person類上是否有VIP註解boolean isPresent = cls.isAnnotationPresent(INFO.class);if (isPresent) {// 取出Person類上的註解Annotation a = cls.getAnnotation(INFO.class);// 擷取VIP註解中的屬性值(調用VIP的抽象方法)INFO vip = (INFO) a;System.out.println(vip.username());System.out.println(vip.age());System.out.println(vip.sex());}// 需求:擷取doWork方法上的Deprecated註解// 1:擷取doWork方法所在類的位元組碼檔案Class doWorkCls = User.class;// 2:擷取doWork方法的Method對象Method m = doWorkCls.getMethod("doWork");System.out.println(m);// 3:擷取當前方法上的註解Deprecated depre = m.getAnnotation(Deprecated.class);System.out.println(depre);}}

運行結果:


上面程式並沒有賦予註解功能。


接下來建立一個Android項目,布局檔案裡面添加兩個控制項:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.annomationdemo.MainActivity" >    <TextView        android:id="@+id/tv_show"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:layout_marginTop="180dp"        android:text="@string/hello_world" />    <Button        android:id="@+id/bt_show"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerHorizontal="true"        android:layout_centerVertical="true"        android:text="Button" /></RelativeLayout>

建立一個註解類:

import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)public @interface getViewTo {    int value() default  -1;}

MainActivity.java中:

public class MainActivity extends ActionBarActivity {@getViewTo(R.id.tv_show)private TextView tv_show;@getViewTo(R.id.bt_show)private Button bt_show;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                //通過註解產生View        getAllAnnomationView();        bt_show.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {tv_show.setText("註解擷取成功");}});    }    /**     * 解析註解,擷取控制項     */private void getAllAnnomationView() {//擷取成員變數Field[] fields = this.getClass().getDeclaredFields();for (Field field : fields) {try {//判斷註解是否為空白if(field.getAnnotations()!=null){//確定註解類型if(field.isAnnotationPresent(getViewTo.class)){//允許修改反射屬性field.setAccessible(true);getViewTo getViewTo = field.getAnnotation(getViewTo.class);//通過findViewById將註解的id,找到View並注入成員變數中field.set(this, findViewById(getViewTo.value()));}}} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();}}}}

這裡就不示範運行結果了,大家運行過後可能有點感覺像ButterKnife,不過ButterKnife比這個強大多了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.