文章目錄
JDK內置註解
@Override
@Override
的作用是標記重寫父類的方法,@Override
只能用於標記方法。編譯器編譯時會校驗使用@Override
標記的方法是否與父類對應方法形式一致。例:
Man.java
public class Man{
private String name;
private float height;
private int weight;
public void setName(String name){};
public void setHeight(float height){};
public void setWeight(int weight){};
}
Woman.java
public class Woman extends Man{
@Override
public void setHeight(int height){
//編譯時會報錯,因爲形參與父類不同
}
}
@Deprecated
@Deprecated
用於提示所修飾的元素(類、方法、變量等)已過時,繼續使用可能會發生危險或者存在更好的選擇。JDK更新過程中不會刪除過時的API,而是爲這些API加上@Deprecated
標籤,使得JDK不建議用戶繼續使用該API的同時,也保證使用了過時API的舊項目能正常運行。
@SuppressWarnings
@SupressWarnings
的作用是抑制編譯器警告。可以用於修飾所有成員。例如一個成員定義了卻未使用(unused)
,就可以使用@SupressWarnings("unused")
來抑制成員未使用(unused)
的警告。再例如使用原類型時抑制警告:
@SupressWarnings({"unused","rawtypes"})
ArrayList list = new ArrayList(); //使用了ArrayList不帶類型參數的原類型
元註解
概述
元註解是用來修飾註解定義
的註解。
@Retention
@Retention
限定了被修飾註解的生命週期
。它的取值有:
//註解在源文件(java文件)中有效(源文件保留),編譯時丟棄
@Retention(RetentionPolicy.SOURCE)
//默認值。註解在class文件中有效(class保留),但不會加載到JVM
@Retention(RetentionPolicy.CLASS)
//註解在運行時有效(運行時保留),JVM會保留註釋,所以程序運行時可以通過反射機制獲取到註解信息
@Retention(RetentionPolicy.RUNTIME)
例:
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnnotation{
String[] value();
}
@Target
@Target
指定被修飾註解可以用來修飾程序中的哪些元素。取值有:
TYPE
:被修飾註解可以修飾class
/interface
/@interface
/enum
。
FIELD
:被修飾註解可以修飾field
。
METHOD
:被修飾註解可以修飾method
。
PARAMETER
:被修飾註解可以修飾parameter
。
CONSTRUCTOR
:被修飾註解可以修飾constructor
。
LOCAL_VARIABLE
:被修飾註解可以修飾local variable(局部變量)
。
ANNOTATION_TYPE
:被修飾註解可以修飾Annotation type
。
PACKAGE
:被修飾註解可以修飾package
。
TYPE_PARAMETER
:被修飾註解可以修飾class parameter(泛型類型參數)
。
TYPE_USE
:被修飾註解可以修飾任何使用類
的元素。
例:
@Target({TYPE,METHOD,CONSTRUCTOR}) //該註解可以用於修飾 類、方法、構造器
public @interface MyAnnotation{
String[] value();
}
**注意:**若未指明@Target
元註解,則該註解默認可以修飾程序中的所有元素。
@Documented
被@Documented
修飾的註解修飾的成員在API文檔中也會顯示出相應的註解,而默認API文檔中是不顯示註解的。
@Inherited
@Inherited
修飾的註解將具有繼承性,即如果一個類被@Inherited
修飾的註解修飾,這個類的子類將自動具有該註解。
自定義註解
使用@interface
關鍵字定義註解:
public @interface MyAnnotation{
/*
成員變量以“無參方法”的形式聲明,“無參方法”的返回值即成員變量的值
*/
int value();
String message();
}
使用方法:
//修飾類
@MyAnnotation(value = 1,message = "type")
public class Person{
//修飾屬性
@MyAnnotation(value = 2,message = "field")
private String name;
//修飾構造器
@MyAnnotation(value = 3,message = "constructor")
public Person(String name){
this.name = name;
}
//修飾方法
@MyAnnotation(value = 4,message = "method")
public String getName(){
return name;
}
//修飾參數
public void setName(@MyAnnotation(value = 5,message = "param") String name){
this.name = name;
}
}
使用default
關鍵字指定成員變量默認值:
public @interface MyAnnotation{
int value() default 0;
String message() default "";
}
此時再使用時可以不用帶參數從而直接使用默認值:
@MyAnnotation
public class Person{
//也可以僅指定部分參數
@MyAnnotation(message = "default test")
public Person(String name){
this.name = name;
}
}
如果註解中沒有成員,這個註解就是一個標識。例如@Override
。
通過反射機制獲取RUNTIME
註解
定義註解
MyAnnotation.java
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation{
int value() default 0;
String message() default "";
}
Person
類
Person.java
@MyAnnotation(message = "Person")
public class Person{
@MyAnnotation(value = 1,message = "name")
private String name;
@MyAnnotation(value = 2,message = "height")
private float height;
@MyAnnotation(value = 3,message = "weight")
private int weight;
@MyAnnotation(value = 4,message = "Person()")
public Person(String name,float height,int weight){
this.name = name;
this.height = height;
this.weight = weight;
}
@MyAnnotation(value = 5,message = "setName()")
public void setName(@MyAnnotation(value = 6,message = "paramName")String name){
this.name = name;
}
@MyAnnotation(value = 7,message = "getName()")
public String getName(){
return name;
}
@MyAnnotation(value = 8,message = "setHeight()")
public void setHeight(@MyAnnotation(value = 9,message = "paramHeight")float height){
this.height = height;
}
@MyAnnotation(value = 10,message = "getHeight()")
public float getHeight(){
return height;
}
@MyAnnotation(value = 11,message = "setWeight()")
public void setWeight(@MyAnnotation(value = 12,message = "paramWeight")int weight){
this.weight = weight;
}
@MyAnnotation(value = 13,message = "getWeight()")
public int getWeight(){
return weight;
}
}
獲取註解的方法
//java.lang.annotation.Annotation
public Annotation[] getAnnotations()
//java.lang.annotation.Annotation
public <A extends Annotation> A getAnnotation(Class<A> annotationClass)
//java.lang.annotation.Annotation
public Annotation[] getDeclaredAnnotations()
//java.lang.annotation.Annotation
public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass)
獲取類的註解
Class<Person> clas = Person.class;
//獲取註解
MyAnnotation annotation = clas.getDeclaredAnnotation(MyAnnotation.class);
//獲取註解成員"value()"值
int value = annotation.value();
//獲取註解成員"message()"值
String message = annotation.message();
System.out.println("value:"+value+",message:"+message);
獲取屬性的註解
Class<Person> clas = Person.class;
//獲取屬性
Field name = clas.getDeclaredField("name");
//使可訪問
name.setAccessible(true);
//獲取註解
MyAnnotation annotation = name.getDeclaredAnnotation(MyAnnotation.class);
//獲取註解成員"value()"值
int value = annotation.value();
//獲取註解成員"message()"值
String message = annotation.message();
System.out.println("value:"+value+",message:"+message);
獲取構造器的註解
Class<Person> clas = Person.class;
//獲取構造器
Constructor<Person> cons =
clas.getDeclaredConstructor(String.class,float.class,int.class);
//使可訪問
cons.setAccessible(true);
//獲取註解
MyAnnotation annotation = cons.getDeclaredAnnotation(MyAnnotation.class);
//獲取註解成員"value()"值
int value = annotation.value();
//獲取註解成員"message()"值
String message = annotation.message();
System.out.println("value:"+value+",message:"+message);
獲取方法的註解
Class<Person> clas = Person.class;
//獲取方法
Method method = clas.getDeclaredMethod("setName",String.class);
//使可訪問
method.setAccessible(true);
//獲取註解
MyAnnotation annotation = method.getDeclaredAnnotation(MyAnnotation.class);
//獲取註解成員"value()"值
int value = annotation.value();
//獲取註解成員"message()"值
String message = annotation.message();
System.out.println("value:"+value+",message:"+message);
獲取參數註解
Class<Person> clas = Person.class;
//獲取方法(或構造器)
Method method = clas.getDeclaredMethod("setHeight",float.class);
//使可訪問
method.setAccessible(true);
//獲取參數
Parameter param = (method.getParameters())[0];
//獲取註解
MyAnnotation annotation = param.getDeclaredAnnotation(MyAnnotation.class);
//獲取註解成員"value()"值
int value = annotation.value();
//獲取註解成員"message()"值
String message = annotation.message();
System.out.println("value:"+value+",message:"+message);
注意:
只有包含@Retention(RetentionPolicy.RUNTIME)
修飾的註解才能使用反射機制獲取。
說明註釋
概述
Java中有三種註釋形式:1.以//
開頭的單行註釋;2.以/*
開頭*/
結尾的多行註釋;3.以/**
開頭*/
結尾的說明註釋。
說明註釋允許在程序中嵌入對程序的說明信息,生成API文檔作爲API調用時的指導。
說明註釋中可以包含以@
開頭標籤,用於對特定信息的描述,例如作者、版本、方法參數和方法返回值等。
常用的說明註釋標籤
1.@author
:用於類註釋。說明類的作者。例:
/**
*@author Lishaoyin
*/
public class Person{}
2.@version
:用於類註釋。說明類的版本。例:
/**
*@version 1.0
*/
public class Person{}
3.@since
:用於類和任意類成員註釋。說明API是在JDK的哪個版本添加的。例:
/**
*@since 1.8
*/
public void setName(String name){} //API在JDK1.8添加
4.@deprecated
:用於類和任意類成員註釋。說明該類成員已過期,不建議使用。例:
/**
*@deprecated this field is deprecated,you can use better choice
*/
private String name;
5.@throws
:用於方法和構造器註釋。說明方法或構造器可能會拋出的異常。例:
/**
*@throws java.io.IOException this method maybe throws IOException
*/
public void setHeight(float height) throws IOException {}
6.@exception
:作用與@throws
相同。
7.@see
:用於類和任意類成員註釋。在生成的文檔中指定一個API文檔超鏈接,用戶點擊後可跳轉至指定內容的API文檔。例:
/**
*@see java.lang.annotation.Annotation
*/
public class Person{}
8.@param
:用於方法和構造器註釋。說明方法或構造器的參數。例:
/**
*@param name String,person's name
*@param height float,person's height
*@param weight int,person's weight
*/
public Person(String name,float height,int weight){}
9.@return
:用於方法註釋。說明方法的返回值。
/**
*@return String,person's name
*/
public String getName(){}
TODO
TODO
是一種用法簡單的計劃標記工具,其作用是將計劃指示信息嵌入到註釋中(可嵌入到三種註釋中的任意一種)。編譯後可使用快速定位跳轉到指定計劃位置,繼續完成計劃中未完成的工作。例:
public class Person{
public String getName(){
//TODO function to get person's name
}
public void setHeight(float height){
/*TODO function to set person's height*/
}
/**
*@param weight int,set person's weight
*TODO function to set person's weight
*/
public String setWeight(int weight){}
}
示例
Person.java
/**
*@author Lishaoyin
*version 1.0
*@since 1.8
*/
public class Person{
private String name;
private float height;
private int weight;
/**
*@param name String,init person's name
*@param height float,init person's height
*@param weight int,init person's weight
*/
public Person(String name,float height,int weight){
this.name = name;
this.height = height;
this.weight = weight;
}
/**
*@param name String,set person's name
*/
public void setName(String name){
this.name = name;
}
/**
*@return String,get person's name
*/
public String getName(){
return name;
}
/**
*@param height float,set person's height
*/
public void setHeight(float height){
this.height = height;
}
/**
*@return float,get person's height
*/
public float getHeight(){
return height;
}
/**
*@throws java.io.IOException this method maybe throws IOException
*@see java.io.IOException
*@param weight int,set person's weight
*/
public void setWeight(int weight) throws java.io.IOException {
this.weight = weight;
}
/**
*@return int,get person's weight
*/
public int getWeight(){
return weight;
}
//TODO function to set person's sex
}