註解是元數據的一種形式,,爲程序提供了一些數據,可是並非程序的一部分。註解對代碼並不直接地提供操做。html
@Entity
java
@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) 被建立出來是爲了支持改進對java程序的分析,是一種保證強類型檢查的方式。在java8 版本中沒有提供一種檢查的框架,可是java 8 容許咱們去寫一個類型檢查的框架,這個框架實現一個或多個模塊,這些模塊做爲java編譯器的插件。
例如: 你想要去保證程序中特定的參數永遠不爲null,你想要去避免出發空指針異常,能夠去自定義一個插件去檢查。你只須要去修改你的代碼,把特定的變量加上標誌能用null賦值的註解。就像這樣
@Notnull String str;
當你去編譯這個代碼的時候,當這個編譯器探測到一些潛在的問題的時候,會打印出警告。容許你去修改代碼避免出現錯誤。當代碼修正後,這個錯誤將不會出如今這個程序中。
不少時候,咱們想在一個聲明或類型上屢次使用一個註解。在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
What is wrong with the following interface?
public interface House { @Deprecated void open(); void openFrontDoor(); void openBackDoor(); }
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() {} }