科目一知識點總結
註解(Annotation)
1、註解是一種引用資料型別,編譯之後也是生成xxx.class
檔案。
2、語法格式:
/* [修飾符列表] @interface 註解型別名{} */
public @interface MyAnnotation{
}
3、註解的使用
一:註解使用時的語法格式@註解型別名
二:註解可以出現在 類、屬性、方法、變數、註解型別上等等。
4、JDK內建的註解java.lang
Deprecated
:不鼓勵程式設計師使用這樣的元素,通常因為它很危險或存在更好的選擇。
Override
:表示一個方法宣告打算重寫超類中的另一個方法宣告。
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override{ }
- 這個註解只能註解方法。
- 這個註解是給編譯器參考的,和執行階段沒有關係。
- 標識性註解給編譯器做參考。Java 中帶有這個註解,編譯器就會進行編譯檢查,如果這個方法不是重寫父類的方法則編譯器報錯。
SuppressWarnings
:指示應該在註釋元素(以及包含在該註釋元素中的所有程式元素)中取消顯示指定的編譯器警告。
元註解
1、元註解:用來標註“註解型別”的“註解”,稱為元註解。
-
Target
:這個元註解用來標註"被標註的註解"可以出現在哪些位置上。@Target(ElementType.METHOD)
:表示被標註的註解只能出現在方法上。 -
Retention
:用來標註“被標註的註解”最終儲存在哪裡。@Retention(RetentionPolicy.SOURCE)
:表示該註解只被保留在Java 原始檔中。(如:@Override在 class 檔案找不到,只能在 java 原始檔中找到)@Retention(RetentionPolicy.CLASS)
:表示該註解只被保留在 class 檔案中。@Retention(RetentionPolicy.RUNTIME)
:表示該註解只被保留在 class 檔案中,並且可以被反射機制讀取到。
註解中定義屬性
public @interface MyAnnotation{ /*MyAnnotation的name屬性*/ String name(); String since(); int age() default 5; //屬性指定預設值,使用註解時有預設值的可以不寫 String value(); }
使用:
1、如果一個註解當中有屬性,則必須給屬性賦值,除非該屬性使用 default 指定了預設值。
@MyAnnotation(name="gao",since="9")
2、如果屬性名為value
並且只有這一個屬性,則使用註解時對應的屬性值可以不寫。
3、註解當中的屬性可以是哪種型別?
答:可以是:byte\short\int\long\float\double\boolean\char\String\Class\列舉型別
及以上型別的陣列形式。
反射註解
如果獲取類上註解的屬性值,必須先獲取類,然後通過類獲取類上的註解,最後獲取註解屬性值。
如果獲取在方法上的註解屬性值,必須先獲取類,然後獲取類的方法,通過方法獲取方法上的註解,最後獲取註解的屬性值。
//只允許該註解標註類、方法
@Target({ElementType.TYPE,ElementType.METHOD})
//希望這個註解可以被反射
@Retention(RetentionPolicy.RNUTIME)
public @interface MyAnnotation{
String value() default "zhang";
}
//註解測試類
@MyAnnotation("gao")
public class MyAnnotationTest{
int i;
public MyAnnotationTest(){
}
@MyAnnotation
public void doSome(){
int i ;
}
}
//反射註解測試類
public class Reflect AnnotationTest{
public static void main(String[] args) throws Exception{
//獲取這個類
Class c = Class.forName("com.reflect.www.MyAnnotationTest");
//判斷是否有@MyAnnotation這個註解,並獲取註解物件和屬性值
if(c.isAnnotationPresent(MyAnnotation.class)){//如果有該註解物件則返回true
//獲取註解物件
MyAnnotation myAnnotation = (MyAnnotation)c.getAnnotation(MyAnnotation.class); //@com.reflect.www.MyAnnotationTest
//獲取註解物件的屬性
String value = myAnnotation.value();
System.out.println(value);//返回最後一次修改的value值
}
}
}
註解在開發中的作用
需求:假設有一個註解@Id
,這個註解只能出現在類上面,當類上有這個註解時,要求這個類中必須有一個 int 型別的 id 屬性,如果沒有則報異常,有則正常執行。
//該註解只能出現在類上
@Target(ElementType.TYPE)
//該註解可以被反射機制讀取
@Retention(RetentionPolicy.RUNTIME)
public @interface Id{
}
//帶有註解的類
@Id
public class Test{
int id;
String name;
}
//測試類
public class AnnotationTest{
public static void main(String[] args){
//獲取類
Class c = Class.forName("com.reflect.www.Test");
//判斷類上是否有註解@Id
if(c.isAnnotationPresent(Id.class)){
//獲取類的屬性
Field[] fields = c.getDeclaredFields();
boolean ok = false; //預設標記是否合法
for(Field[] field : fields){
if("id".equals(field.getName()) && "int".equals(field.getType().getSimpleName())){ //當有id屬性且識int型別時,表示合法
ok = true;
break;
}
}
//當不合法時報錯
if(!ok){
throw new HasNotIdPropertyException("被@Id註解標註的類中沒有int型別的id屬性,不合法!");
}
}
}
}
//自定義異常
public class HasNotIdPropertyException extends RuntimeException{
public HasNotIdPropertyException(){}
public HasNotIdPropertyException(String s){
super(s);
}
}