註解入門

java註解

註解是什麼?

註解是元數據的一種形式,,爲程序提供了一些數據,可是並非程序的一部分。註解對代碼並不直接地提供操做。html

做用:

  • 告知編譯器一些信息,例如檢查重寫(@Override)、抑制警告(@SuppressWarnings)
  • 編譯器以及部署期 的處理: 軟件工具能夠處理註解去生成代碼,xml文件
  • 運行時處理:一些註解能夠在運行時被檢查到

基礎

註解的格式

@Entityjava

@Author( name = "Benjamin Franklin", date = "3/27/2003" )express

哪裏能夠被使用:

能夠被用在 類、方法、字段、或者參數api

public enum ElementType {
/* Class, interface (including annotation type), or enum declaration /
TYPE,
/* Field declaration (includes enum constants) /
FIELD,
/* Method declaration /
METHOD,
/* Formal parameter declaration /
PARAMETER,
/* Constructor declaration /
CONSTRUCTOR,
/* Local variable declaration /
LOCAL_VARIABLE,
/* Annotation type declaration /
ANNOTATION_TYPE,
/* Package declaration /
PACKAGE,
/*Type parameter declaration/
TYPE_PARAMETER,
/* Use of a type/
TYPE_USE
}數組

在java8 中,註解也能夠用到type上oracle

Class instance creation expression:
new @Interned MyObject();
Type cast:
myString = (@NonNull String) str;
implements clause:
class UnmodifiableList<T> implements
@Readonly List<@Readonly T> { ... }
Thrown exception declaration:
void monitorTemperature() throws
@Critical TemperatureException { ... }框架

聲明一個註解類型

用於代替註釋less

public class Generation3List extends Generation2List {

// Author: John Doe
// Date: 3/17/2002
// Current revision: 6
// Last modified: 4/12/2004
// By: Jane Doe
// Reviewers: Alice, Bill, Cindy

// class code goes here

}jvm

‎要添加此相同的元數據與註釋‎,首先須要去定義一個註解類型。語法以下:ide

注:註解裏只容許基本類型,加上枚舉,註解,String。

public @interface ClassPreamble {
String author();
String date();
int currentRevision() default 1;
String lastModified() default "N/A";
String lastModifiedBy() default "N/A";
// 使用數組
String[] reviewers();
}

註解的定義有點像interface,其實註解也是interface的一種形式。

註解的元素聲明有點像接口的方法,註解的元素能夠設置默認值。若是要使其出如今javadoc 中,須要加上@Document 註解

預約義註解類型

有些註解在java se api 中已經被定義好了。一些註解類型是被java 編譯器所使用,有一些註解被用於其餘註解上。

java語言中被使用

@Deprecated

@Override

@SuppressWarnings

@SafeVarargs

@FunctionalInterface

應用於其餘註解

運用於其餘註解的註解叫元註解。在.java.lang.annotation中被定義了一些元註解。

@Retention 註解用於指定註解被存儲的時期

RetentionPolicy.SOURCE 這個意味着註解僅僅在源碼中被保留,將會被編譯器所忽略

RetentionPolicy.CLASS 這個意味着註解會被保留到編譯期,可是會被jvm所忽略

RetentionPolicy.RUNTIME 這個意味着註解將會被保留到jvm中,也就是說能夠在運行時中使用。

@Documented 在生成javadoc文檔的時候,會顯示這個註解的內容

@Target 表示這個註解做用的地方

  • ElementType.ANNOTATION_TYPE 能夠被運用到註解類型
  • ElementType.CONSTRUCTOR 能夠運用到構造方法上.
  • ElementType.FIELD 能夠運用到字段或屬性上
  • ElementType.LOCAL_VARIABLE 能夠被用到局部變量上.
  • ElementType.METHOD 能夠運用到方法上.
  • ElementType.PACKAGE 能夠在包路徑上 .
  • ElementType.PARAMETER 能夠運用到方法參數上.
  • ElementType.TYPE 能夠被用到類 .

@Inherited 表示這個註解類能夠從他的父類被繼承,僅僅能夠被用於類的聲明。

@Repeatable 在java8 中被引入,這個標記的註解能夠被屢次聲明

Type Annotation and pluggable type system

類型註解(type annotation) 被建立出來是爲了支持改進對java程序的分析,是一種保證強類型檢查的方式。在java8 版本中沒有提供一種檢查的框架,可是java 8 容許咱們去寫一個類型檢查的框架,這個框架實現一個或多個模塊,這些模塊做爲java編譯器的插件。

例如: 你想要去保證程序中特定的參數永遠不爲null,你想要去避免出發空指針異常,能夠去自定義一個插件去檢查。你只須要去修改你的代碼,把特定的變量加上標誌能用null賦值的註解。就像這樣

@Notnull String str;

當你去編譯這個代碼的時候,當這個編譯器探測到一些潛在的問題的時候,會打印出警告。容許你去修改代碼避免出現錯誤。當代碼修正後,這個錯誤將不會出如今這個程序中。

重複註解 (repeating annotation)

不少時候,咱們想在一個聲明或類型上屢次使用一個註解。在java8 中,重複註解提供了咱們須要的這種功能。

爲了兼容,重複註解是存儲在註解容器(container annotation)中的,這個容器是由編譯器自動生成的。爲了編譯器去完成這個,在代碼中須要去實現兩步聲明。

第一步: 定義一個重複註解類

這個重複註解類必定要備Repeatable元註解去標記。下面是定義一個@Schedule 重複註解:

@Repeatable(Schedules.class)  // 容器類型
public @interface Schedule {
String dayOfMonth() default "first";
String dayOfWeek() default "Mon";
int hour() default 12;
}

這個元註解的值(圓括號中的值) ,就是java編譯器生成的註解容器(container annotation存儲註解 的類。(就是說,這個值,就是容器的類型,這個容器是用來存放的是註解)。在這個例子中,這個註解容器(container annotation) 的類型就是Schedules,所以,重複註解@Schedule 被存儲在@Schedules註解中。

第二步:聲明一個容器註解類型

這個容器註解類型必定要包含一個value元素,他的類型是數組類型的。這個組件類型必定是重複註解的類型,聲明Schedules這個容器註解類型以下:

public @interface Schedules {
Schedule[] value(); // 一個Schedule 的數組
}

獲取註解(Retrieving Annotation)

在反射api中有好幾種獲取註解的方法。有些方法能夠獲取一個註解。例如

[AnnotatedElement.getAnnotation(Class)] 若是圓括號中僅僅有一個註解(值),那就原封不動地返回一個註解(值),若是圓括號中有多個註解,也能夠經過去獲取註解容器去獲取。以這種方式,代碼能夠繼續運行。另外一個就是,java 8 中新添的,能夠一次性返回多個註解,例如AnnotatedElement.getAnnotations(Class<T>)。

參考資料:java lesson

  1. What is wrong with the following interface?

    public interface House {
        @Deprecated
        void open();
        void openFrontDoor();
        void openBackDoor();
    }
  2. Consider this implementation of the House interface, shown in Question 1.

    public class MyHouse implements House {
        public void open() {}
        public void openFrontDoor() {}
        public void openBackDoor() {}
    }
相關文章
相關標籤/搜索