自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

框架開發(fā)之Java注解的妙用

開發(fā) 架構(gòu)
如果你還不會使用注解,你肯定不好意思對別人說你學(xué)過Spring,你學(xué)過Mybatis,因為它們用了大量的注解??梢娮⒔庠陂_發(fā)領(lǐng)域已經(jīng)使用的非常廣泛了。

 [[279602]]

如果你還不會使用注解,你肯定不好意思對別人說你學(xué)過Spring,你學(xué)過Mybatis,因為它們用了大量的注解??梢娮⒔庠陂_發(fā)領(lǐng)域已經(jīng)使用的非常廣泛了。

注解的好處:

1.能夠讀懂別人寫的代碼,特別是框架相關(guān)的代碼。

2.本來可能需要很多配置文件,需要很多邏輯才能實現(xiàn)的內(nèi)容,就可以使用一個或者多個注解來替代,這樣就使得編程更加簡潔,代碼更加清晰。

3.(重點)刮目相看。

(但是怎么樣才能讓別人刮目相看呢?會用注解不是目的,最重要的是要使用自定義注解來解決問題。)

舉個栗子:

如果面試的時候,你跟老板說你會使用注解,老板覺得你這個人還行;但是如果老板發(fā)現(xiàn)你會自定義注解解決問題,老板肯定就會眼前一亮。

注解這一概念是在java1.5版本提出的,說Java提供了一種原程序中的元素關(guān)聯(lián)任何信息和任何元數(shù)據(jù)的途徑的方法。

一、Java中的常見注解

1)JDK注解

JDK注解一共分為三類:

 

案例:

我們先新建一個接口people,如下: 

  1. public interface people {  
  2.    public String name();  
  3.    public int age();  
  4.    public void work();  

然后再建一個類Child實現(xiàn)類people這個接口,并實現(xiàn)該類的方法: 

  1. public class Child implements people {  
  2.    @Override  
  3.    public String name() {  
  4.        return null;  
  5.    }  
  6.    @Override  
  7.    public int age() {  
  8.        return 0;  
  9.    }  
  10.    @Override  
  11.    public void work() {  
  12.    } 

看到這里,我們發(fā)現(xiàn)這里的所有方法都會加上一個@Override標記,它告訴我們,同時也告訴編譯器我們的這些方法肯定覆蓋了類people里面的方法的。假如說,我現(xiàn)在把類people里面的某一個方法注釋掉: 

  1. //public String name(); 

再看類Child里面的name方法就會報錯。這樣,以后大家看到@Override的時候就能想到這個方法是覆蓋了某個接口的方法的。

然后,我們回過頭來看類people里面有一個work的方法。這里我們可以理解為人是要工作的,但是并不是所有的人都在工作,那么怎么辦呢?如果說這個接口正在用,我們不能刪除這個方法,這個時候我們就可以這樣: 

  1. @Deprecated  
  2. public void work(); 

@Deprecated標記就表明這個方法已經(jīng)過時了,在實際中,它又有什么樣的應(yīng)用場景呢?我們在建一個測試類: 

  1. public class Test { 
  2.     public void work() {  
  3.        people people=new Child();  
  4. !      people.work();  
  5.    }  

這個時候我們會發(fā)現(xiàn)myeclipse會給一個警告,并且在work中間出現(xiàn)一個破折號,意思就是這個方法已經(jīng)過時了。那么問題來了,雖然這個方法過時了,但是我們就是那么傲嬌,一定要用它,怎么辦呢?只需要這樣: 

  1. public class Test {  
  2.    @SuppressWarnings("deprecation")  
  3.    public void work() {  
  4.        people people=new Child();  
  5.        people.work();  
  6.    }  

這樣我們就忽略了這個警告。@SuppressWarnings("deprecation")就表示我們忽略了deprecation這樣的一個警告。

2)Java第三方注解

 

二、注解的分類

1)按照運行機制劃分:

【源碼注解→編譯時注解→運行時注解】

源碼注解:只在源碼中存在,編譯成.class文件就不存在了。

編譯時注解:在源碼和.class文件中都存在。像前面的@Override、@Deprecated、@SuppressWarnings,他們都屬于編譯時注解。

運行時注解:在運行階段還起作用,甚至?xí)绊戇\行邏輯的注解。像@Autowired自動注入的這樣一種注解就屬于運行時注解,它會在程序運行的時候把你的成員變量自動的注入進來。

2)按照來源劃分:

【來自JDK的注解——來自第三方的注解——自定義注解】

3)元注解:

元注解是給注解進行注解,可以理解為注解的注解就是元注解。

三、自定義注解

我們分四步來解析自定義注解:

自定義注解的語法要求: 

  1. @Target({ElementType.METHOD,ElementType.TYPE})  
  2. @Retention(RetentionPolicy.RUNTIME)  
  3. @Inherited  
  4. @Documented  
  5. public @interface Description {  
  6.    String desc();  
  7.    String author();  
  8.    int age() default 18;  

首先我們要明確這不是一個接口,它是使用@interface關(guān)鍵字定義的一個注解。

然后我們看下面的幾個方法,String desc();雖然它很類似于接口里面的方法,其實它在注解里面只是一個成員變量(成員以無參無異常的方式聲明),int age() default 18;(成員變量可以用default指定一個默認值的)。

最后我們要知道:

①.成員類型是受限制的,合法的類型包括基本的數(shù)據(jù)類型以及String,Class,Annotation,Enumeration等。

②.如果注解只有一個成員,則成員名必須取名為value(),在使用時可以忽略成員名和賦值號(=)。

③.注解類可以沒有成員,沒有成員的注解稱為標識注解。

元注解:

有沒有發(fā)現(xiàn)上面那段代碼有一個沒有說呢?沒錯,它們就是我們所說的元注解: 

  1. @Target({ElementType.METHOD,ElementType.TYPE})  
  2. @Retention(RetentionPolicy.RUNTIME)  
  3. @Inherited  
  4. @Documented 

我們先看第一行:@Target是這個注解的作用域,ElementType.METHOD是這個注解的作用域的列表,METHOD是方法聲明,除此之外,還有:

CONSTRUCTOR(構(gòu)造方法聲明),FIELD(字段聲明),LOCAL VARIABLE(局部變量聲明),METHOD(方法聲明),PACKAGE(包聲明),PARAMETER(參數(shù)聲明),TYPE(類接口)

第二行:@Retention是它的生命周期,前面不是說注解按照運行機制有一個分類嘛,RUNTIME就是在運行時存在,可以通過反射讀取。除此之外,還有:

SOURCE(只在源碼顯示,編譯時丟棄),CLASS(編譯時記錄到class中,運行時忽略),RUNTIME(運行時存在,可以通過反射讀取)

第三行:@Inherited是一個標識性的元注解,它允許子注解繼承它。

第四行:@Documented,生成javadoc時會包含注解。

使用自定義注解:

使用注解的語法:

@<注解名>(<成員名1>=<成員值1>,<成員名1>=<成員值1>,...)

案例: 

  1. @Description(desc="i am Color",author="boy",age=18 
  2.    public String Color() {  
  3.        return "red";  
  4.    } 

這里的Description是我們剛才在自定義注解語法要求里面定義的注解噢,然后我們可以給它的每一個成員變量賦值,注意數(shù)據(jù)類型。值得注意的是,因為我們前面定義的作用域是在方法和類接口上,所以這個注解在Color()方法上使用是沒問題的。

解析注解

概念:

通過反射獲取類 、函數(shù)或成員上的運行時注解信息,從而實現(xiàn)動態(tài)控制程序運行的邏輯。

準備工作:

接下來,我們就開始測試了: 

  1. public class ParseAnn {  
  2.    public static void main(String[] args) {  
  3.        try {  
  4.            // 使用類加載器加載類  
  5.            Class c = Class.forName("com.test.Child");  
  6.            // 找到類上面的注解  
  7.            boolean isExist = c.isAnnotationPresent(Description.class);  
  8.            // 上面的這個方法是用這個類來判斷這個類是否存在Description這樣的一個注解  
  9.            if (isExist) {  
  10.                // 拿到注解實例,解析類上面的注解  
  11.                Description d = (Description) c.getAnnotation(Description.class);  
  12.                System.out.println(d.value());  
  13.            }  
  14.        } catch (ClassNotFoundException e) {  
  15.            e.printStackTrace();  
  16.        }  
  17.    }  

輸出的結(jié)果: 

  1. i am class annotation 

可以看到,我們成功的解析了Child類上面的注解。

接下來,我們繼續(xù)解析方法上的注解: 

  1. //獲取所有的方法  
  2.            Method[] ms = c.getMethods();  
  3.            // 遍歷所有的方法  
  4.            for (Method m : ms) {  
  5.                boolean isExist1 = m.isAnnotationPresent(Description.class);  
  6.                if (isExist1) {  
  7.                    Description d1=m.getAnnotation(Description.class);  
  8.                    System.out.println(d1.value());  
  9.                }  
  10.            } 

輸出的結(jié)果: 

  1. i am class annotation  
  2. i am method annotation 

可以看到,我們成功的解析了方法上面的注解。 

  1. //另一種解析方法  
  2.            for (Method m : ms) {  
  3.                //拿到方法上的所有的注解  
  4.                Annotation[] as=m.getAnnotations();  
  5.                for (Annotation a : as) {  
  6.                    //用二元操作符判斷a是否是Description的實例  
  7.                    if (a instanceof Description) {  
  8.                        Description d=(Description) a;  
  9.                        System.out.println(d.value());  
  10.                    }  
  11.                }  
  12.            } 

也可以得到上面的效果。

此時,如果把Description類里面的元注解改一下,比如:

@Retention(RetentionPolicy.RUNTIME)→@Retention(RetentionPolicy.SOURCE),再運行程序,結(jié)果會成怎樣呢?如果改成CLASS呢?大家要不要試一試? 

 

責(zé)任編輯:龐桂玉 來源: Java團長
相關(guān)推薦

2023-02-15 14:02:52

HutoolMapProxy工具包

2022-06-09 07:27:14

JavaSpring容器

2011-08-03 14:49:57

框架

2017-03-02 13:19:43

dubbo分布式框架

2022-05-30 11:17:44

Spring容器配置

2011-07-27 13:57:36

iPhone 游戲 Cocos2d

2013-07-22 14:28:07

網(wǎng)絡(luò)安全框架NIST

2023-05-08 15:59:27

UI自動化腳本鴻蒙

2015-10-16 09:59:52

SwiftCocoa

2011-07-07 10:50:09

Cocoa 框架

2020-09-07 12:53:56

.NET 5Web應(yīng)用框架

2013-04-23 09:31:12

Winform開發(fā)框架

2022-10-26 09:57:52

VectorRustC++

2021-10-18 10:14:26

鴻蒙HarmonyOS應(yīng)用

2010-01-27 08:44:56

ASP.NET MVC

2009-01-07 11:07:27

AJAXASP.NET.NET

2016-03-23 11:05:58

Socket開發(fā)框架分析

2011-07-19 09:38:41

一維數(shù)組Junit靜態(tài)成員

2023-02-24 14:52:20

Redis存儲開發(fā)

2018-11-26 07:04:59

神經(jīng)網(wǎng)絡(luò)優(yōu)化函數(shù)
點贊
收藏

51CTO技術(shù)棧公眾號