Java注解学习笔记

Java注解(Annotation)

1. 注解(Annotation)介绍

注解(Annotation)是从Jdk1.5引入的新技术

1.1 注解(Annotation)的作用

  • 不是程序本身,可以对程序作出解释
  • 可以被其他程序(比如:编译器读取)。

**注解信息的处理流程是注解与注释的最大区别。**如果没有注解信息处理流程,则注解毫无意义。

1.2 注解(Annotation)的格式

  • 以“@注释名”在代码中存在,如:

@Override,@Autowired

1.3 注解(Annotation)使用的地方

可以添加在package, class, method, field等上面,相当于给它们添加了额外的辅助信息,我们可以通过反射机制变成实现对这些元数据的访问。

2. 内置注解

2.1 @Override

定义在java.lang.Override中,此注释只适用于修辞方法,表示一个方法声明打算重写超类中的另一个方法声明。

2.2 @Deprecated

定义在java.lang.Deprecated中,此注释可用于修辞方法、属性、类,表示不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。

2.3 @SuppressWarnings

定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息。如:

@SuppressWarnings(“unchecked”)

@SuppressWarnings(value={“unchecked”,“deprecation”})

@SuppressWarnings(“all”)

3. 自定义注解@interface

  • 使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口

  • 格式及要点:

1)public @interface 注解名 {定义体}

2)其中的每一个方法实际上是声明了一个配置参数。

3)方法的名称就是参数的名称。

4)返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。

5)可以通过default来声明参数的默认值。

6)如果只有一个参数成员,一般参数名为value。

注解元素必须要有值。我们定义注解元素时,经常使用空字符串、0作为默认值。也经常使用负数(比如:-1)表示不存在的含义

例子:

public @interface Annotation01 {
	
	String name() default "";
	int age() default 0;
	int id() default -1;
	
	String[] schools() default {"清华大学", "北京大学"};

}
public @interface Annotation02 {
	String value();
}

4. 元注解

  • 元注解的作用就是负责注解其他注解。 Java定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。
  • 这些类型和它们所支持的类在java.lang.annotation包中可以找到
    • @Target
    • @Retention
    • @Documented
    • @Inherit

4.1 @Target

用于描述注解的使用范围(即:被描述的注解可以用在什么地方)

修饰范围取值ElementType
package 包PACKAGE
类、接口、枚举、Annotation类型TYPE
类型成员(方法、构造方法、成员变量、枚举)CONSTRUCTOR:用于描述构造器
Field:用于描述域
METHOD:用于描述方法
方法参数和本地变量LOCAL_VARIABLE:用于描述局部变量
PARAMETER:用于描述参数
  • @Target(value=ElementType.TYPE)
  • @Target(value={ElementType.METHOD,ElementType.TYPE})

4.2 @Retention

表示需要在什么级别保存该注释信息,用于描述注解的生命周期。

RetentionPolicy作用
SOURCE在源文件中有效
CLASS在class文件中有效
RUNTIME在运行时有效,RUNTIME可以被反射机制读取

4.3 @Documented

声明注解能够被javadoc等识别。

4.4 @Inherit

声明子类可以继承此注解,如果一个类A使用此注解,则类A的子类也继承此注解。

4.5 例子

定义一个自定义注解(使用元注解,每个元注解都是可选,非必选)。

@Target(value={ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Annotation01 {
	
	String name() default "";
	int age() default 0;
	int id() default -1;
	
	String[] schools() default {"清华大学", "北京大学"};

}
@Target(value= {ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Annotation02 {
	String value();

}
@Annotation01
public class demo2 {
	
	@Annotation01(name="zhangsan", id=1001, age=28, schools={"西安交通大学","西北工业大学"})
	public void test1() {
		
	}
	
	@Annotation02("aaa")
	public void test2() {
		
	}

}

5. 通过反射解析注解

5.1 定义一个Table注解

@Target(value= {ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
	String value();

}

5.2 定义一个Field注解

@Target(value= {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Field {
	
	String columnName();
	String type();
	int length();

}

5.3 将注解添加到实体类User中

@Table("tb_user")
public class User {
	
	@Field(columnName="id", type="int", length=10)
	private int id;
	@Field(columnName="user_name", type="varchar", length=20)
	private String name;
	@Field(columnName="age", type="int", length=3)
	private int age;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}

}

5.4 测试通过反射获得注解信息

public class TestUserAnnotation {

	public static void main(String[] args) {
		try {
			Class clazz = Class.forName("com.stormkai.annotation.User");
		
			//获得类的所有有效注解
			Annotation[] annotations = clazz.getAnnotations();
			for(Annotation a: annotations) {
				System.out.println("a="+a);
			}
			
			//获得类的指定的注解
			Table t = (Table) clazz.getAnnotation(Table.class);
			System.out.println("t.value()="+t.value());
			
			//获得类的属性name的注解
			java.lang.reflect.Field f = clazz.getDeclaredField("name");
			Field field = f.getAnnotation(Field.class);
			System.out.println(field.columnName()+"---"+field.type()+"---"+field.length());
			
            //获取类的所有属性的注解
			Field field1;
			java.lang.reflect.Field[] ff = clazz.getDeclaredFields();
			for(int i=0; i<ff.length; i++) {
				ff[i].setAccessible(true);
				
				field1 = clazz.getDeclaredField(ff[i].getName()).getAnnotation(Field.class);
				System.out.println(field1.columnName()+"---"+field1.type()+"---"+field1.length());
				
			}
		
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

测试结果:

a=@com.stormkai.annotation.Table(value=tb_user)
t.value()=tb_user
user_name---varchar---20
id---int---10
user_name---varchar---20
age---int---3

5.5通过解析注解拼接DDL语句

public class TestUserAnnotation {

	public static void main(String[] args) {
		try {
			Class clazz = Class.forName("com.stormkai.annotation.User");
			//根据获得的表名,字段的信息,拼出DDL语句
			Annotation[] annotations = clazz.getAnnotations();
			Table t = (Table) clazz.getAnnotation(Table.class);
			StringBuilder sb = new StringBuilder();
			sb.append("create table "+t.value()+"( ");
			
			Field field;
			java.lang.reflect.Field[] ff = clazz.getDeclaredFields();
			for(int i=0; i<ff.length; i++) {
				ff[i].setAccessible(true);
				
				field = clazz.getDeclaredField(ff[i].getName()).getAnnotation(Field.class);
				System.out.println(field.columnName()+"---"+field.type()+"---"+field.length());
				sb.append(field.columnName()+" "+field.type()+"("+field.length()+"), ");
				
			}
			String str = sb.substring(0, sb.lastIndexOf(","));
			str+=" );";
			
			
			System.out.println(str);
		
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

输出结果:

id---int---10
user_name---varchar---20
age---int---3
create table tb_user( id int(10), user_name varchar(20), age int(3) );
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值