註解,元數據的一種形式,提供關於程序不是程序自己的一部分數據。註解對代碼的操做沒有直接影響。
註解有多用途,如:
a、用於編譯信息。經過編譯器檢測錯誤or抑制警告
b、編譯時和部署時的處理。軟件工具可以處理註解信息生成代碼,xml文件等
c、運行時的處理。一些註解能夠在運行時被檢查
一、註解基礎
註解的格式
最簡單的形式如:@Entity
@:指明編譯器下面是一個註解
下面註解名稱是Override
@Override
void mySuperMethod() {…}
註解能夠包含帶名稱or不帶名稱,及這些元素的值,如
@Author(
name=」Benjamin Franklin」
date=」3/27/2003」
)
class MyClass(){...}
或
@SuppressWarnings(value=「unchecked」)
void myMethod(){...}
若此時只有一個元素value時,該元素名稱能夠忽略,如:
@SuppressWarnings(「unchecked」)
void myMethod(){...}
若該註解沒有元素時,那圓括號能夠忽略,如@Override例子
能夠在同一個聲明處使用多個註解
@Author(name = "Jane Doe")
@EBook
class MyClass(){...}
若註解有相同的類型,稱爲重複註解,目前只有java SE8 支持,如:
@Author(name = "Jane Doe")
@Author(name = "John Smith")
class MyClass(){...}
註解類型能夠是Java SE API的java.lang或java.lang.annotation包中定義的類型,前面例子中 SuppressWarnings和Override都時預約義java註解。你也可自定義註解類型。Author和EBook爲自定義註解類型
註解的使用
註解能夠用於:類的聲明,字段,方法,和其餘的程序元素。
因Java SE8的發佈,註解也能夠應用於類型的使用,如:
a、類實例的建立表達式
new @Interned MyObject();
b、類型轉換
myString = (@NonNull String)str;
c、implements 從句
class UnmodifiablleList<T> implements
@Readonly List<@Readonly T> {...}
d、拋出異常的聲明
void monitorTemperature() throws
@Critical TemperatureException {...}
二、聲明一個註解類型
大多數註解替換代碼中的註釋
假如某個軟件集團在每一個類的開始使用註釋提供重要信息:
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
}
使用註解來添加這些相同的元數據,你必須首先定義註解類型,如:
@interface ClassPreamble {
String author();
String date();
int currentRevision() default 1;
String lastModified() default "N/A";
String lastModifiedBy() default "N/A";
// Note use of array
String[] reviewers();
}
註解類型的定義相似於接口定義,只是在關鍵字interface 以前添加@符號。註解類型是一種接口形式,上面註解定義包含註解類型的元素聲明,看起來很像方法,注意:它們有可選的默認值。
註解類型定義完成後,你可使用相應元素值填充後使用該註解,如:
@ClassPreamble (
author = "John Doe",
date = "3/17/2002",
currentRevision = 6,
lastModified = "4/12/2004",
lastModifiedBy = "Jane Doe",
// Note array notation
reviewers = {"Alice", "Bob", "Cindy"}
)
public class Generation3List extends Generation2List {
// class code goes here
}
注意:使 @ClassPreamble的信息出如今javadoc生成的文檔中,你必須在定義 @ClassPreamble時使用@Documented,如:
@Documented
@interface ClassPreamble {
// Annotation element definitions
}
三、預約義的註解類型
Java SE API中預約義註解集。一些經過編譯器被使用,一些提供給其餘註解。
由java語言使用的註解類型
a、@Deprecated:指明標記元素已廢棄,應再也不使用。當程序中的方法、類、字段使用@Deprecated時,編譯器會生成一個警告。當一個元素被廢棄,它也應該在javadoc中記錄廢棄@deprecated標籤,注意javadoc中的d爲小寫,如:
// Javadoc comment follows
/**
* @deprecated
* explanation of why it was deprecated
*/
@Deprecated
static void deprecatedMethod() { }
}
b、@Override:指明編譯器該元素是覆蓋父類中聲明的元素,如:
// mark method as a superclass method
// that has been overridden
@Override
int overriddenMethod() { }
重寫方法不是必需要求該標註,但它有助於防止錯誤,若一個方法標記@Override識別,編譯器會生成一個正確重寫父類中一個方法的錯誤。
c、@SuppressWarnings:指明編譯器抑制特定的警告信息,不然會生成一個警告,下面使用一個廢棄的方法,編譯器一般會生成一個警告,使用該註解來抑制該警告。
// use a deprecated method and tell
// compiler not to generate a warning
@SuppressWarnings("deprecation")
void useDeprecatedMethod() {
// deprecation warning
// - suppressed
objectOne.deprecatedMethod();
}
每一個編譯器警告屬於一類,java規範列出2類:deprecation和unchecked。unckecked警告會在接口與寫傳統代碼(泛型以前)發生,爲了抑制多個類別的警告,可以使用:
@SuppressWarnings({"unchecked", "deprecation"})
d、@SafeVarargs:適用於方法or構造器,斷言代碼不執行潛在不安全的操做在它的Varargs參數上,當使用該註解時,關於Varargs使用unchecked警告將抑制。
e、@FunctionalInterface:Java SE 8引入,聲明一個由java 語言定義的函數接口
提供給其餘註解的類型
註解能夠提供給另外註解,稱元註解,在java.lang.annotation包中定義以下元註解
a、@Retention:指明如何存儲註解:
RetentionPolicy.SOURCE只保留在源代碼級別,被編譯器忽略
RetentionPolicy.CLASS保留在編譯時,但被JVM忽略
RetentionPolicy.RUNTIME保留在JVM,所依經過運行環境使用
b、@Docmented:指明該元素應該使用javadoc工具進行歸檔,默認,註解在javadoc中是不被包含的。
c、@Target:指明另外一個註解限制使用java元素註解能夠應用,目標註解指定一個下面的元素類型的值。
ElementType.ANNOTATION_TYPE應用與註釋類型
ElementType.CONSTRUCTOR、ElementType.FIELD、ElementType.LOCAL_VARIABLE、ElementType.METHOD、ElementType.PACKAGE、ElementType.PARAMETER、ElementType.TYPE
d、@Inherited:指明該註解類型能夠從父類繼承,只適用於類聲明的註解
e、@Repeatable:Java SE 8引入,代表註解能夠不止一次應用到相同的聲明or類型的使用
四、類型註解和可插拔式系統
Java SE8以前,註解僅能應用與聲明部分,Java SE 8發佈後,註解也能夠應用於任何類型使用的地方,這種形式的註解稱爲類型註解。
類型註解是用來支持並提升java程序的分析方法,確保更強的類型檢查。Java 8發佈沒有提供類型檢查的框架,但它容許你寫or下載一個類型檢查的框架,實現爲一個or多個插件可插拔式模塊中使用java編譯器的結合。
如,你想確保程序中某個特定變量不被設置爲null;避免NullPointerException。你能夠編寫一個自定義插件來檢查它。你能夠修改特定變量的代碼註解,代表它是不爲null,如:
@NonNull String str;
當編譯代碼時,在命令行包含NonNull,編譯器檢測可能的問題並打印一個警告,容許你修改代碼避免這個錯誤。
五、可重複註解
java 8發佈後,容許你在聲明or類型使用時不止一次使用相同註解。
例如,編寫一個操做計時器服務,在給定一個時間or一個定義的調度器上運行一個方法。如今你設置計時去運行方法doPeriodicCleanup,在每月的最後一天和每週五的pm 11點,如:
@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
public void doPeriodicCleanup() { ... }
爲了兼容,可重複註解存儲java編譯器自動生成一個註解容器中,爲實現編譯器,你代碼須要2個聲明要求:
a、聲明一個可重複的註解類型
註解類型必須使用@Repeatable元註解標註,如
@Repeatable(Schedule.class)
public @interface Schedule { ... }
b、聲明包含註解的類型
包含註解必須有一個使用一個數組類型的元素值,數組類型必須是一個可重複註解類型。如:
public @interface Schedules {
Schedule[] value;
}
java