1、註解html
1.全部的註解都是類。java
2.全部的註解都是Annotation接口的子類。數組
接口摘要ide |
|
全部 annotation 類型都要擴展的公共接口。this |
3.定義方式spa
public @interface TestAnnotation { }
4.能夠註解的位置:任何地方均可以,可是要知足註解的具體限制,默認註解能夠加在任意位置上code
package com.kdyzm.anotation; @TestAnnotation public class Test { @TestAnnotation private String name; @TestAnnotation public void show(@TestAnnotation String name) { @TestAnnotation String age; System.out.println(name); } }
5.使用註解限制註解的位置htm
使用@Target註解限制自定義註解的註解位置。對象
@Target(value={ElementType.METHOD})//聲明只能對方法進行註解,接收數組參數
具體能夠限制的類型:ElementType枚舉
/* * %W% %E% * * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package java.lang.annotation; /** * A program element type. The constants of this enumerated type * provide a simple classification of the declared elements in a * Java program. * * <p>These constants are used with the {@link Target} meta-annotation type * to specify where it is legal to use an annotation type. * * @author Joshua Bloch * @since 1.5 */ public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE }
6.限制註解在運行時是否刪除
使用@Retention限制註解的存在範圍
@Retention(value=RetentionPolicy.RUNTIME)//聲明該註解在運行時保存,即便用方法isAnnotationPresent方法返回值是true
具體的參數見:RetentionPolicy枚舉(保留策略枚舉)。
/* * %W% %E% * * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package java.lang.annotation; /** * Annotation retention policy. The constants of this enumerated type * describe the various policies for retaining annotations. They are used * in conjunction with the {@link Retention} meta-annotation type to specify * how long annotations are to be retained. * * @author Joshua Bloch * @since 1.5 */ public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME }
7.註解的做用
(1)編譯時限制做用
public class MyServlet extends HttpServlet { @Override public void doGet(ServletRequest req,String name) throws ServletException, IOException { } }
由於父類沒有這個方法,因此加上@Override註解以後就會編譯報錯。
(2)運行時反射
全部類的字節碼對象Class、Field、Method、Constructor都擁有一個方法
|
|
|
|
默認自定義註解在運行時刪除,可是經過其它註解能夠定義該自定義註解的生存範圍。怎樣定義見6。
8.註解的實例化
永遠不要實例化註解類,由於註解類是經過系統經過反射實例化的。
9.給註解定義屬性/方法(官方說法爲屬性)。
(1)value屬性:官方推薦的屬性,也是默認的屬性,使用方法:public String value();(這種定義方法看上去好像是方法,可是其實是屬性,暫且爲屬性)
(2)修飾符必須是public,能夠存在static、final修飾,可是不能有其它修飾符。
(3)默認值:使用關鍵字default定義,若是沒有設置默認值,則在使用註解的時候必須顯示賦值才能經過編譯。
10.註解定義示例。
package com.kdyzm.anotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(value={ElementType.METHOD})//聲明只能對方法進行註解,接收數組參數 @Retention(value=RetentionPolicy.RUNTIME)//聲明該註解在運行時保存,即便用方法isAnnotationPresent方法返回值是true public @interface MyAnnotation { public String value(); public String name() default "noName"; }
2、使用註解小示例。
1.獲取註解的屬性值。
使用Class類、Field類、Method類、Constructor類的getAnnotation方法。
|
||
|
|
2.自定義註解小練習。
(1)自定義註解MyAnnotation
package com.kdyzm.anotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(value={ElementType.METHOD})//聲明只能對方法進行註解,接收數組參數 @Retention(value=RetentionPolicy.RUNTIME)//聲明該註解在運行時保存,即便用方法isAnnotationPresent方法返回值是true public @interface MyAnnotation { public String value(); public String name() default "noName"; }
(2)在UseMyAnnotation類中使用自定義註解
package com.kdyzm.setOnMyAnnotation; import com.kdyzm.anotation.MyAnnotation; //使用自定義註解,該註解只能加在方法上。 public class UseMyAnnotation { private String name; private int age; @MyAnnotation("setName方法") public void setName(String name) { this.name=name; } @MyAnnotation("getName方法") private String getName() { return name; } private int getAge() { return age; } @MyAnnotation("setAge方法") public void setAge(int age) { this.age=age; } }
(3)解析UseMyAnnotation類的全部內容並對註解進行解析。
package com.kdyzm.demo; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import com.kdyzm.anotation.MyAnnotation; //測試自定義註解MyAnnotation的使用,使用MyAnnotation類和UseMyAnnotation類兩個類 public class MyTest { public static void main(String[] args) throws Exception { String className="com.kdyzm.setOnMyAnnotation.UseMyAnnotation"; Class cls=Class.forName(className); //實例化該類。 Object obj=cls.newInstance(); //獲取該類中的全部方法 Method []methods=cls.getDeclaredMethods(); //遍歷該方法數組。 for(Method method:methods) { boolean flag=method.isAnnotationPresent(MyAnnotation.class);//判斷是否進行了方法的註解 if(flag)//若是進行了方法的註解 { System.out.print("被註解的方法:"); //判斷是不是私有的方法 if(method.getModifiers()==Modifier.PRIVATE) { //若是是私有的方法則設置暴力破解 method.setAccessible(true); System.out.println("該方法私有!方法名爲:"+method.getName()); } else { System.out.println("該方法共有!方法名爲:"+method.getName()); } //若是被註解了,輸出該註解屬性值 MyAnnotation annotation=method.getAnnotation(MyAnnotation.class); String value=annotation.value(); String name=annotation.name(); System.out.println("該註解的內容是:"+value+","+name); } else//說明是沒有被註解的方法 { System.out.print("沒有被註解的方法:"); //判斷是不是私有的方法 if(method.getModifiers()==Modifier.PRIVATE) { //若是是私有的方法則設置暴力破解 method.setAccessible(true); System.out.println("該方法私有!方法名爲:"+method.getName()); } else { System.out.println("該方法共有!方法名爲:"+method.getName()); } } System.out.println(); } } }
(4)運行結果。
沒有被註解的方法:該方法私有!方法名爲:getAge
被註解的方法:該方法共有!方法名爲:setAge
該註解的內容是:setAge方法,noName
被註解的方法:該方法私有!方法名爲:getName
該註解的內容是:getName方法,noName
被註解的方法:該方法共有!方法名爲:setName
該註解的內容是:setName方法,noName