Java中的注解
来源:互联网 发布:深圳航天信息开票软件 编辑:程序博客网 时间:2024/05/21 11:14
注解(也被称为 元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。
2、标准注解与元注解
Java内置了三种标准注解和四种元注解
3种标准注解(定义在java.lang中):
@Override 表示当前的方法定义将覆盖超类中的方法。如果你不小心拼写错误,或者方法签名对不上覆盖的方法,编译器就会发出错误提示。
@Deprecated 如果程序员使用了注解为它的元素,那么编译器会发出警告信息。
@SuppressWarning 关闭当前的编译器警告信息。
4种元注解(元注解专职负责注解其他的注解)
@Target 表示该注解可以用于什么地方。可能的ElementType参数包括:
CONSTRUCTOR:构造器的声明
FIELD:域声明(包括enum实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口(包括注解类型)或enum声明
@Retention 表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:
SOURCE:注解将被编译器丢弃
CLASS:注解在class文件中可用,但会被VM丢弃
RUNTIME:VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息
@Document 将此注解包含在Javadoc中
@Inherited 允许子类继承父类中的注解
3、自定义一个注解
自定义一个简单的注解(没有元素的注解称为标记注解)
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Test {}自定义一个包含元素的注解
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface UseCase {public int id();public String description() default "no description";}
4、使用自定义注解
import java.util.List;import com.zhangmingji.annotation.UseCase;public class PasswordUtils {@UseCase(id=47, description="password 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> prePasswords, String password){return !prePasswords.contains(password);}}5、编写注解处理器
import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Collections;import java.util.List;import com.zhangmingji.annotation.UseCase;import com.zhangmingji.use.PasswordUtils;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);}}
运行结果:
Found Use Case:47 password must contain at least one numericFound Use Case:48 no descriptionFound Use Case:49 New passwords can't equal previously used onesWarning: Missing use case-506、注解元素
在前面我们已经定义了一个包含元素id、description的注解,
注解元素可用的类型如下:
所有基本类型(int,float,boolean等)
String
Class
enum
Annotation
以上类型的数组
如果你使用了其他类型,那么编译器就会报错;也不允许使用任何包装类型;注解也可以作为基本元素类型,也就是说注解可以嵌套
7、默认值限制
(1)、元素不能有不确定的值。也就是说,元素必须要么具有默认值,要么使用注解时提供元素的值。
(2)、对于非基本类型的元素,无论在源代码中声明时,或是在注解接口中定义默认值时,都不能以null作为其值。
(3)、注解不支持继承。
8、通过注解生成建表语句
package com.zhangmingji.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.TYPE)//类、接口、或者ENUM声明@Retention(RetentionPolicy.RUNTIME)public @interface DBTable {public String name() default "";}
package com.zhangmingji.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface Constraints {boolean primaryKey() default false;boolean allowNull() default true;boolean unique() default false;}
package com.zhangmingji.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface SQLString {int value() default 0;String name() default "";Constraints constraints() default @Constraints;}
package com.zhangmingji.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface SQLInteger {String name() default "";Constraints constraints() default @Constraints;}
使用以上自定义的注解
package com.zhangmingji.use;import com.zhangmingji.annotation.Constraints;import com.zhangmingji.annotation.DBTable;import com.zhangmingji.annotation.SQLInteger;import com.zhangmingji.annotation.SQLString;@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 String getHandle(){return this.handle;}public String getFirstName(){return this.firstName;}public String getLastName(){return this.lastName;}public String toString(){return handle;}public Integer getAge(){return age;}}
实现处理器
package com.zhangmingji.process;import java.lang.annotation.Annotation;import java.lang.reflect.Field;import java.util.ArrayList;import java.util.List;import com.zhangmingji.annotation.Constraints;import com.zhangmingji.annotation.DBTable;import com.zhangmingji.annotation.SQLInteger;import com.zhangmingji.annotation.SQLString;public class TableCreator {public static void main(String[] args) throws Exception {if(args.length < 1){System.out.println("arguments: anotationed classes");System.exit(0);}for(String className : args){Class<?> cl = Class.forName(className);DBTable dbTable = cl.getAnnotation(DBTable.class);if(null == dbTable){System.out.println("no DBTable anotations in class " + className);continue;}String tableName = dbTable.name();//如果名字为空,则使用类名if(tableName.length() < 1){tableName = cl.getName().toUpperCase();}List<String> columDefs = new ArrayList<String>();for(Field field : cl.getDeclaredFields()){String columName = null;Annotation[] anns = field.getDeclaredAnnotations();if(anns.length < 1){continue; //}if(anns[0] instanceof SQLInteger){SQLInteger sInt = (SQLInteger) anns[0];//如果没有指定名称,则使用属性名称if(sInt.name().length() < 1){columName = field.getName().toUpperCase();}else{columName = sInt.name();}columDefs.add(columName + " INT" + getConstraints(sInt.constraints()));}if(anns[0] instanceof SQLString){SQLString sString = (SQLString) anns[0];if(sString.name().length() < 1){columName = field.getName().toUpperCase();}else{columName = sString.name();}columDefs.add(columName + " VARCHAR(" + sString.value() + ")" + getConstraints(sString.constraints()));}}StringBuilder createCommand = new StringBuilder("CREATE TABLE " + tableName + "(");for(String columDef : columDefs){createCommand.append("\n " + columDef + "," );}String tableCreate = createCommand.substring(0, (createCommand.length() - 1)) + ");";System.out.println("Table create SQL for " + className + " is :\n" + tableCreate);}}/** * 构造约束 * @param con * @return */public static String getConstraints(Constraints con){String contraints = "";if(!con.allowNull()){contraints += " NOT NULL";}if(con.primaryKey()){contraints += " PRIMARY KEY";}if(con.unique()){contraints += " UNIQUE";}return contraints;}}
运行结果:
Table create SQL for com.zhangmingji.use.Member is :CREATE TABLE MEMBER( FIRSTNAME VARCHAR(30), LASTNAME VARCHAR(50), AGE INT, HANDLE VARCHAR(30) PRIMARY KEY);
以上内容来自《Java编程思想》第四版,仅作为学习和总结。
- Java中的注解
- Java中的注解
- --java中的注解
- java中的注解
- java中的元注解
- java中的注解
- java中的注解
- Java中的注解
- eclipse中的java注解
- Java中的注解
- java中的注解
- java 中的注解
- Java中的注解
- java中的注解 详解
- java中的注解用法。
- Java中的注解(@ Annotation)
- Java中的注解
- java中的注解
- 信息架构之史前时代
- NOJ1010 数的计算
- [python]模拟浏览器下载网页
- 设计模式——生成器模式(Builder Pattern)
- BananaPro 上wpa_supplicant 工具使用
- Java中的注解
- 《TCP/IP详解卷2:实现》笔记--TCP的输入(续)
- 使用CmdMarkdown编写CSDN博客(以本文为例)
- [Python]操作Mysql数据库
- php设计模式——简单工厂模式
- No suitable driver found for jdbc:mysql://localhost:3306/****
- Cookie介绍
- Android重启原因分析
- 改变 MFC 对话框 static 控件的字体颜色