java todo注释_Java自定义注解
1、注解 Annotation
也稱為元數據,和注釋 comment 的區別:Annotation 可以提供編譯期的一些操作,比如類型檢查。Annotation 是Java 5 引入的新特性。Java 5 在 java.lang 中內置了三種標準注解。
@Override:表示當前方法其實是覆蓋父類的方法
@Deprecated:表示該類或方法不建議使用了,未來有可能被廢棄或者移除。
@SuppressWarnings:給編譯器一條指令,告訴它對范圍內的某些類型的警告保持靜默。
同一個元素上可以使用多個不同注解。
2、自定義注解
因為 Java 內置的注解無法滿足五花八門的需求,所以就需要我們自定義注解。
Java 內置了四種元注解,幫助申明自定義注解。
@Target:表示該注解可以使用在什么地方,參數是枚舉類 ElementType:
TYPE:類,接口(包括注解類型),枚舉類
FIELD:字段,變量
METHOD:方法
PARAMETER:參數
CONSTRUCTOR:構造器
LOCAL_VARIABLE:局部變量
ANNOTATION_TYPE:注解
PACKAGE:包
TYPE_PARAMETER:自定義類型參數
TYPE_USE:該注解能使用在使用類型的任意語句中,使用方法見下圖
TYPE_USE
@Retention:表示需要在什么級別保存該注解信息(生命周期),參數 RetentionPolicy 包括
SOURCE:源碼級別,注解將被編譯器丟棄
CLASS:在編譯器生成的 CLASS 文件中可用,但是會被 VM 丟棄。(默認的就是該級別)
RUNTIME:運行期保留該注解,所以此時可以通過反射機制來讀取注解的信息
@Documented:將注解包含在 javadoc 中
@Inherited:允許子類繼承父類的注解
自定義注解案列:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
public int id();
public String description() default "no description";
}
public class PasswordUtils {
@UseCase(id = 47, description = "password must contain one number")
public boolean validatePassword(String password){
return true;
}
@UseCase(id = 48)
public String encryptPassword(String password){
return "encryptPassword()";
}
@UseCase(id = 49, description = "new password can't equal previously used ones")
public boolean checkouForNewPassword(){
return false;
}
}
配置參數可以使用的類型如下:
所有的基本類型。(int,float,boolean等)
String
Class
enum
Annotation
以上類型的數組
對于上面 UseCase 的demo,寫一個程序來進行處理
public class UseCaseTracker {
public static void main(String[] args) {
// TODO Auto-generated method stub
List useCases = new ArrayList();
Collections.addAll(useCases, 47, 48, 49, 50);
trackUseCases(useCases, PasswordUtils.class);
}
public static void trackUseCases(List useCases, Class> cl) {
for (Method m : cl.getDeclaredMethods()){
// getDeclaredAnnotation 返回指定類型的 注解對象
UseCase uc = m.getDeclaredAnnotation(UseCase.class);
if (uc != null){
System.out.println("Found UseCase :" + uc.id() + "\t" + uc.description());
useCases.remove(new Integer(uc.id()));
}
}
System.out.println("--------------------------------------");
for (int i : useCases){
System.out.println("Warning : Miss use case --" + i);
}
}
}
結果如下:
Found UseCase :47 password must contain one number
Found UseCase :48 no description
Found UseCase :49 new password can't equal previously used ones
--------------------------------------
Warning : Miss use case --50
看一個復雜的案列
//告訴注解處理器,需要生成一個數據庫表
//這個注解只能用于類,接口,enum
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
public String name() default "";
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraints {
//這些元素都有默認值,這樣我們就不必強迫程序員必須賦值了
boolean primaryKey() default false;
boolean allowNull() default true;
boolean unique() default false;
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLString {
//定義了元素名為value,在符合條件時,我們使用時,可以直接在括號內輸入value的值就ok了。
int value() default 0;
String name() default "";
Constraints constraints() default @Constraints;
}
/**
* SQLInteger 和 SQLString一樣,都是要求在javabean上,根據不同的數據類型使用不同的注解
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLInteger {
String name() default "";
//注解嵌套
Constraints constraints() default @Constraints;
}
/**
* 我們的目的就是為該javabean生成一個創建表的語句
*/
@DBTable(name = "MEMBER")
public class Member {
@SQLString(30)
String firstName;
@SQLString(50)
String lastName;
@SQLInteger
Integer age;
@SQLString(value = 30,
constraints = @Constraints(primaryKey = true))
String handle;
static int memberCount;
}
public class TableCreator {
public static void main(String[] args) throws Exception{
StringBuilder createCommand = new StringBuilder();
String className = "test.annotation.database.Member";
Class> cl = Class.forName(className);
DBTable dbTable = cl.getAnnotation(DBTable.class);
String tableName = dbTable.name();
//如果名字為空,就使用類名
if (tableName.length() < 1){
tableName = cl.getName().toUpperCase();
}
createCommand.append(
"CREATE TABLE " + tableName + "(");
List columnDefs = new ArrayList();
for (Field field : cl.getDeclaredFields()){
String columnName = null;
Annotation[] anns = field.getDeclaredAnnotations();
if (anns.length < 1){
continue;
}
//這里的寫法之所以簡單,因為我們每個Field上面最多只有一個 注解
if (anns[0] instanceof SQLInteger){
SQLInteger sInt = (SQLInteger)anns[0];
//沒有名字的話,我們就使用Field的名字來做為 列名
if (sInt.name().length() < 1){
columnName = field.getName();
}else {
columnName = sInt.name();
}
columnDefs.add(columnName + " INT " + getConstraints(sInt.constraints()));
}
if (anns[0] instanceof SQLString){
SQLString sString = (SQLString)anns[0];
if (sString.name().length() < 1){
columnName = field.getName();
}else {
columnName = sString.name();
}
columnDefs.add(columnName + " VARCHAR(" + sString.value()
+ ")" + getConstraints(sString.constraints()));
}
}
for (String columnDef : columnDefs){
createCommand.append("\n\t" + columnDef + ",");
}
//移除最后的一個逗號
String tableCreate = createCommand.substring(0, createCommand.length()-1) + ");";
System.out.println("TABLE Creation SQL for " + className + " is: \n" + tableCreate);
}
//解析出 Constraints 注解的內容
private static String getConstraints(Constraints con){
String constraints = "";
if (!con.allowNull()){
constraints += " Not Null";
}
if (con.primaryKey()){
constraints += " PRIMARY KEY ";
}
if (con.unique()){
constraints += " NNIQUE ";
}
return constraints;
}
}
輸出結果:
TABLE Creation SQL for test.annotation.database.Member is:
CREATE TABLE MEMBER(
firstName VARCHAR(30),
lastName VARCHAR(50),
age INT ,
handle VARCHAR(30) PRIMARY KEY );
總結
以上是生活随笔為你收集整理的java todo注释_Java自定义注解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VML标记与通用属性
- 下一篇: 任务管理器中的PID是什么 怎么查看