最簡單的理解,注解就和標簽一樣,是對抽象事物的解釋;
這是在看http://blog.csdn.net/briblue/article/details/73824058
博客時最先總結的一句話但都看完之后感覺注解是一個標簽但他也是對一個方法或類的聲明,比如說這個類是我寫的,我可以給他貼一個標簽,上面貼上本人的大名
我來用我當時看博客的疑問思路來解釋一下,首先我們是不是要問既然解釋和理解都這么復雜,那我們用實際例子來說明注解到底是干什么的,然后來一行一行的深入了解一下。
好了廢話到這里先來我的小例子(這也是上面這篇博客里的小例子,先說明一下,防止被人錘):
我們先來寫一個自己的注解(帶着疑問看完這篇博客再說):
@Retention(RetentionPolicy.RUNTIME)//這個是元注解之一,這一行就是注解說明這個注解在運行時還有效(這行注釋很重要) public @interface Jiecha { }
我們在寫一個類,這個類里的方法我們用我們的注解
public class NoBug { @Jiecha public void suanShu(){ System.out.println("1234567890"); } @Jiecha public void jiafa(){ System.out.println("1+1="+1+1); } @Jiecha public void jiefa(){ System.out.println("1-1="+(1-1)); } @Jiecha public void chengfa(){ System.out.println("3 x 5="+ 3*5); } @Jiecha public void chufa(){ System.out.println("6 / 0="+ 6 / 0); } public void ziwojieshao(){ System.out.println("我寫的程序沒有 bug!"); } }
可以看到我們的方法都加上了我們的注解
那么我們就用一下我們的注解,
如果一點都看不懂下面的代碼就先跳到代碼下面的文字部分,看完再回來看代碼
public class MainActivity extends AppCompatActivity { TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv=findViewById(R.id.tv); NoBug noBug = new NoBug();//new出我們寫的檢查bug類的對象 Class aClass = noBug.getClass();//獲取到class對象 Method[] dm = aClass.getDeclaredMethods();//將NoBug類中的所有方法都存在dm數組中 StringBuilder log = new StringBuilder();//創建一個StringBuilder來拼接我們的錯誤報告 // 記錄異常的次數 int errornum = 0;//定義一個int類型的數值來記錄我們報了幾次錯 for ( Method m: dm ) {//循環遍歷我們的數組(就是我們定義的類里面的方法) // 只有被 @Jiecha 標注過的方法才進行測試 if ( m.isAnnotationPresent( Jiecha.class )) {//如果這個方法上有我們的注解我們就進行測試 try { m.setAccessible(true);//打開獲取私有方法的權限 m.invoke(noBug, null);//執行這個m方法 } catch (Exception e) { // TODO Auto-generated catch block //e.printStackTrace(); errornum++;//報錯數加一 log.append(m.getName());//獲取當前報錯方法的名字 log.append(" "); log.append("has error:"); log.append("\n\r caused by "); //記錄測試過程中,發生的異常的名稱 log.append(e.getCause().getClass().getSimpleName()); log.append("\n\r"); //記錄測試過程中,發生的異常的具體信息 log.append(e.getCause().getMessage()); log.append("\n\r"); } } } log.append(aClass.getSimpleName()); log.append(" has "); log.append(errornum); log.append(" error."); // 生成測試報告 tv.setText(log.toString()); } }
首先,我們會發現里面使用了Java的反射,這是為什么,細心的你會看到我粘貼的代碼里的第一行注釋,我們的注解是到運行時還有效的,而我們這個代碼的主要功能是檢查我們報的錯
而運行時的錯誤,當然是在運行時,而我們的Java文件在編譯后會變成Class文件才能在JVM中運行(如果你不知道JVM那就自己問一下度娘吧),所有我們需要用反射才能獲取到我們
在運行時報的錯,這里先給大家把反射中的注釋都加上,可以方便大家看代碼。
這就是注解的一個使用,如果還是看不懂,那么我們最簡單的一個例子,我們在用到過時的方法時這個方法上面會被畫上一條線
這條線怎么來的呢,就是這個方法被加上了@Deprecated這個注解,自己可以寫着調用一下,這個注解就是用來警告我們,這個方法已經過時了;
這個時候我們再來說其實注解就和其實同 classs 和 interface 一樣,注解也屬於一種類型。它是在 Java SE 5.0 版本中開始引入的概念。
那么我們怎么定義一個注解的:
和寫abstract class一樣我們這里要寫@interface
public @interface MyZj { String name(); int age(); }
而里面就是要寫注解的屬性也叫做成員變量。注解只有成員變量,沒有方法。注解的成員變量在注解的定義中以“無形參的方法”形式來聲明,其方法名定義了該成員變量的名字,其返回值定義了該成員變量的類型。就是上面的這種形態;
我們在使用的時候
@MyZj(name="***",age = 1) public class Myclass { }
這就是最簡單的使用然后是元注解在上面的那個博客里非常詳細,這里就不再重復寫了,和Java預置的注解比如我們的重寫@Override
官方的注解的說法:
注解是一系列元數據,它提供數據用來解釋程序代碼,但是注解並非是所解釋的代碼本身的一部分。注解對於代碼的運行效果沒有直接影響。
注解有許多用處,主要如下:
- 提供信息給編譯器: 編譯器可以利用注解來探測錯誤和警告信息
- 編譯階段時的處理: 軟件工具可以用來利用注解信息來生成代碼、Html文檔或者做其它相應處理。
- 運行時的處理: 某些注解可以在程序運行的時候接受代碼的提取
這就是注解最初步的了解然后可以多看看上面的這個帖子,慢慢就會了解注解的;