【Java EE 學習 24 上】【註解詳解】

1、註解html

  1.全部的註解都是類。java

  2.全部的註解都是Annotation接口的子類。數組

接口摘要ide

Annotation測試

全部 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
}
ElementType.java

  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
}
RetentionPolicy.java

  7.註解的做用

    (1)編譯時限制做用

public class MyServlet extends HttpServlet {
    @Override
    public void doGet(ServletRequest req,String name)
            throws ServletException, IOException {
    }
}

    由於父類沒有這個方法,因此加上@Override註解以後就會編譯報錯。

    (2)運行時反射

    全部類的字節碼對象Class、Field、Method、Constructor都擁有一個方法

 該方法用於判斷類上、字段上、方法上、構造方法上是否存在註解,若是存在則返回true,不然返回false

 boolean

isAnnotation()
          若是此 Class 對象表示一個註釋類型則返回 true。

    默認自定義註解在運行時刪除,可是經過其它註解能夠定義該自定義註解的生存範圍。怎樣定義見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方法。  

 

<A extends Annotation>
A

getAnnotation(Class<A> annotationClass)
          若是存在該元素的指定類型的註釋,則返回這些註釋,不然返回 null。

  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
相關文章
相關標籤/搜索