程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 【JAVA基礎】注解,java注解

【JAVA基礎】注解,java注解

編輯:JAVA綜合教程

【JAVA基礎】注解,java注解


以下內容參考java編程思想-4,jdk版本為jdk5.0,有點老-_-|||

什麼是注解

JAVA SE5引入,也稱元數據,可以直接添加到代碼中,用來完整描述程序所需的信息,而這些信息是無法用Java來表達的;

內置注解

jdk5.0中內置了三種標准注解和四種元注解;

三種標准注解,定義在java.lang中:

@Override  //表示子類方法覆蓋父類方法

@Deprecated //已過時,不建議使用的API

@SuppressWarnings //取消編譯器警告

四種元注解:

@Target  //指定該注解可以用在什麼地方

可選參數:

CONSTRUCTOR:構造器聲明

FIELD:域聲明

LOCAL_VARIABLE:局部變量聲明

METHOD:方法聲明

PACKAGE:包聲明

PARAMETER:參數聲明

TYPE:類、接口聲明

@Retention //表明該注解在哪一級別可用

可選參數:

SOURCE:注解將被編譯器丟棄;

CLASS:注解在class文件中可用,但會被VM丟棄;

RUNTIME:VM在運行期間也保留注解,可以通過反射機制讀取注解信息;

@Documented//表明將此注解包含在Javadoc中

@Inherited //允許子類繼承父類的注解

基本語法

自定義注解

標記注解

定義一個@Test注解,如下代碼所示,可以看到,注解的定義與接口類似,事實上注解與接口一樣,也會被編譯成class文件;

package annotations;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
    
}

在注解中,一般都會包含一些元素以表示某些值,當分析處理注解時,程序可以讀取這些值;

上面的@Test注解不包含元素,被稱為標記注解;

包含元素的注解

下面代碼定義了一個包含元素的注解,元素的定義類似於方法,定義中包含了元素的數據類型,如下,id為int類型,description為String類型,且包含一個默認值;

package annotations;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
    public int id();

    public String description() default "no description";
}

注意,注解元素可用的類型如下:

所有的基本數據類型(int,double...)

String

Class

enum

Annotation

數組(以上類型為元素)

如果使用其它類型編譯器會報錯,特別提醒,Integer,Double等基本數據類型的包裝類型也是不允許的;

另外,元素是不能有不確定的值,要麼有默認值,要麼提供元素的值,且不能為null;

注解使用

上面定義的@UseCase注解的使用如下所示,很簡單,在方法前面寫上注解,並指定元素的值,如果未指定的話將使用默認值;

package annotations;

import java.util.*;

public class PasswordUtils {
    @UseCase(id = 47, description = "Passwords must contain at least one numeric")
    public boolean validatePassword(String password) {
        return (password.matches("\\w*\\d\\w*"));
    }

    @UseCase(id = 48)
    public String encryptPassword(String password) {
        return new StringBuilder(password).reverse().toString();
    }

    @UseCase(id = 49, description = "New passwords can't equal previously used ones")
    public boolean checkForNewPassword(List<String> prevPasswords, String password) {
        return !prevPasswords.contains(password);
    }
} 

編寫注解處理器

利用JAVA的反射機制,可以查找注解標記,下面是一個簡單的注解處理器,用於解析上面提到的@UserCase注解,主要使用到了Class類的getDeclaredMethods()方法和Method類的getAnnotation(Class<T> annotationClass)方法;getDeclaredMethods返回類中聲明的所有方法,getAnnotation返回指定的注解;

package annotations;

import java.lang.reflect.*;
import java.util.*;

public class UseCaseTracker {
    public static void trackUseCases(List<Integer> useCases, Class<?> cl) {
        for (Method m : cl.getDeclaredMethods()) {
            UseCase uc = m.getAnnotation(UseCase.class);
            if (uc != null) {
                System.out.println("Found Use Case:" + uc.id() + " "
                        + uc.description());
                useCases.remove(new Integer(uc.id()));
            }
        }
        for (int i : useCases) {
            System.out.println("Warning: Missing use case-" + i);
        }
    }

    public static void main(String[] args) {
        List<Integer> useCases = new ArrayList<Integer>();
        Collections.addAll(useCases, 47, 48, 49, 50);
        trackUseCases(useCases, PasswordUtils.class);
    }
}

注解常見使用場景

描述數據庫表結構與類關系映射(hibernate...)

單元測試(junit...)

一些配置等(spring...)

...

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved