java 注解Annotation

github 参考demo

1、认识Annotation

JDK1.5开始,Java增加了对元数据(即类的组成单元数据)的支持,也就是(Annotation)注解,他是代码里做的特殊标记,这些标记可以在编译,类加载,运行时在不改变原有逻辑的情况下,被读取,并执行相应的处理,通过使 Annotation,程序员可以在源文件中嵌入一些补充的信息。代码分析工具,开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。Annotation类似于修饰符一样被使用,可以用于包,类,构造方法,方法,成员变量,参数,局部变量的声明。

注意:
Annotation是一个接口
java.lang.Annotation接口.

2、系统定义的Annotation

在JDK 1.5之后,在系统中提供了三个Annotation,分别是:@Override、@Deprecated、@SuppressWarnings。

  • @Override
    表示当前的方法定义将覆盖超类中的方法。如果你不小心拼写错误,或者方法签名对不上被覆盖的方法,编译器就会发出错误提示。

  • @Deprecated
    表示的是一个类或方法已经不再建议继续使用了,标记为已过时。

  • @SuppressWarnings
    表示关闭不当的编译器警告信息。
    @SuppressWarnings(“unchecked”)//未检查的转化,如集合没有指定类型
    @SuppressWarnings(“unused”) //未使用的变量
    @SuppressWarnings(“resource”) //有泛型未指定类型
    @SuppressWarnings(“path”) //在类路径,原文件路径中有不存在的路径
    @SuppressWarnings(“deprecation”) //使用了某些不赞成使用的类和方法
    @SuppressWarnings(“fallthrough”) //switch语句执行到底没有break关键字
    @SuppressWarnings(“serial”)//某类实现Serializable 但是没有定义serialVersionUID 这个需要但是不必须的字段
    @SuppressWarnings(“rawtypes”) //没有传递带有泛型的参数
    @SuppressWarnings(“all”) //全部类型的警告

3、自定义Annotation

注解应用需要三个步骤:

  • (1)编写注解
  • (2)在类上应用注解
  • (3)对应用了注解的类进行反射操作的类

自定义Annotation的语法如下:
访问控制权限 @interface Annotation名称{}
例如:
public @interface MyAnnotation {}

在Annotation中定义变量

public @interface MyAnnotation {
	public String name();
	public String info();
}

定义变量后,在调用此Annotation时必须设置变量值。

@MyAnnotation(name = “vince", info = “hello")
public class Demo {
}

通过default指定变量默认值,
有了默认值在使用时可以不设值

public @interface MyAnnotation {
	public String name() default “vince";
	public String info() default “hello";
}

定义一个变量的数组,接收一组参数

public @interface MyAnnotation {
	public String[] name();
}

使用时指定数组值

@MyAnnotation(name = { “jack", “vince" })
public class Demo {
}

使用枚举限制变量取值范围

public enum Color {
	RED, GREEN, BLUE
}
public @interface MyAnnotation {
	public Color color();
} 

4、Retention和RetentionPolicy

Annotation要想决定其作用的范围,通过@Retention指定,而Retention指定的范围由RetentiontPolicy决定,RetentionPolicy指定了三种范围:

范围描述
public static final RetentionPolicy SOURCE在java源程序中存在, 编译时检查,提供给编译器使用,如,@override
public static final RetentionPolicy CLASS在java生成的class中存在
public static final RetentionPolicy RUNTIME在java运行的时候存在

示例:

@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	public String name();
}

5、反射与Annotation

一个Annotation真正起作用,必须结合反射机制,在反射中提供了以下的操作方法:java.lang.reflect.AccessibleObject

方法名称描述
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)判断是否是指定的Annotation
public Annotation[] getAnnotations()得到全部的Annotation

示例:

Class<?> cls = Class.forName(“com.vince.annotation.Test");
Method met = cls.getMethod(“setName"); // 找到setName()方法
if (met.isAnnotationPresent(MyAnnotation.class)) {
	MyAnnotation my = (MyAnnotation) met.getAnnotation(MyAnnotation.class);
	String name = my.name();
	String info = my.info();
	System.out.println("name = " + name);
	System.out.println("info = " + info);
}

6、@Documented注解

此注解表示的是文档化,可以在生成doc文档的时候添加注解。

@Documented
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	public String name();
	public String info();
}
可以增加一些DOC注释。
/**
   * 这个方法是从Object类中覆写而来的
   */
@MyAnnotation(name = “vince", info = “teacher")
public String toString() {
	return "hello";
}

7、@Target注解

@Target注解表示的是一个Annotation的使用范围,不指定就是全范围适用。

范围描述
public static final ElementType TYPE只能在类或接口或枚举上使用
public static final ElementType FIELD在成员变量使用
public static final ElementType METHOD在方法中使用
public static final ElementType PARAMETER在参数上使用
public static final ElementType CONSTRUCTOR在构造中使用
public static final ElementType LOCAL_VARIABLE局部变量上使用
public static final ElementType ANNOTATION_TYPE只能在Annotation中使用
public static final ElementType PACKAGE只能在包中使用

8、@Inherited注解

@Inherited表示一个Annotation是否允许被其子类继承下来。

示例:

@Inherited
@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	public String name();
	public String info();
}

使用时允许被其子类所继承。

package cn.saul.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 自定义注解
 * @author moushuai
 *
 */
//注解的使用范围
@Target(value = {ElementType.TYPE, ElementType.METHOD,  ElementType.CONSTRUCTOR})
//作用范围 
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	public String name();
	public int id();
	public int age() default 2; //给变量设置默认值
	public String[] likes(); //定义一个数组变量
	public Color color(); //定义一个枚举变量
}
package cn.saul.annotation;

public enum Color {
	RED,
	BLUE,
	WHITE
}
package cn.saul.annotation;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Setter
@Getter
@ToString
@MyAnnotation(name = "huahua", id=123, likes = {"fish","meat"},color = Color.WHITE)
public class Cat {
	private String name;
	private int id;
	private int age;
	private String[] likes;
	private Color color;
	
	public Cat(String name, int id, int age) {
		super();
		this.name = name;
		this.id = id;
		this.age = age;
	}
	
	public Cat() {
		super();
	}

}
package cn.saul.annotation;

import java.lang.annotation.Annotation;
import org.junit.Test;

public class MyAnnotationTest {
	
	private Cat cat;
	//反射处理注解
	@Test
	public void test() {
		Class<?> class1 = Cat.class;
		
		//获取类上应用的所有注解
		Annotation[] annotations = class1.getAnnotations();
		MyAnnotation myAnnotation = null;
		for (int i = 0; i < annotations.length; i++) {
			if (annotations[i].annotationType().getName().equals("cn.saul.annotation.MyAnnotation")) {
				myAnnotation = (MyAnnotation) annotations[i];
				
			}
		}
		//获取注解上的变量
		String name = myAnnotation.name();
		int age = myAnnotation.age();
		Color color = myAnnotation.color();
		String[] likes = myAnnotation.likes();
		int id = myAnnotation.id();
		try {
			cat = (Cat) class1.newInstance();
			cat.setAge(age);
			cat.setColor(color);
			cat.setId(id);
			cat.setLikes(likes);
			cat.setName(name);
			System.out.println(cat);
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值