注解

一、java内置注解
@Override:标识覆盖超类中的方法。
@Deprecated:使用了该注解的,编译器会发出警告信息。
@SuppressWarnings:关闭编译器警告。

二、定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test{
	public String name();
	public String des() default "default des";
}

定义注解时,需要为其制定元注解,用来描述注解将用于什么地方,@Target,@Retention即为元注解。

四种元注解
@Target:标识注解应该用于什么地方–CONSTRUCTOR(构造器声明),FIELD(域声明,包括enum实例),LOCAL_VARIABLE(局部变量声明),METHOD(方法),PACKAGE(包),PARAMETER(参数),TYPE(类、接口或enum)。
@Retention:表示在什么级别保存该注解信息–SOURCE(源代码),CLASS(类文件),RUNTIME(运行时)。
@Documented:将此注解包含在Javadoc中。
@Inherited:允许子类继承父类中的注解

name和des的定义类似于方法定义,而不是变量定义:

public String name;
public String des;

default给予des一个默认值。

使用eg

public class TestUse{
	@Test(name = "method1", des = "exec mothod1")
	public void method1(){
		...
	}

	@Test(name = "method2")  //没有给des赋值,使用默认值
	public void method2(){
		...
	}
	
	@Test(des = "exec mothod3")
	public void method3(){
		...
	}
}

没有元素的注解,称为标记注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test2{
}

三、注解处理器

public class TestTracker{
	public static void trackTest(Class<?> c) {
		for(Method m : c.getDeclareMethods()) {
			Test t = c.getAnnotaion(Test.class);
			if (null != t) {
				System.out.println(t.id() + "-----" + t.des());
			}
		}
	}
}
public static void main(String[] args) {
	testTracker(TestUse.class)
}

c.getAnnotaion(XXX.class) : 返回指定类型的注解对象,没有该类型注解则返回null。

用于变量的注解eg:

注解构建:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestField{
}

使用:

public class MyField{
	@TestField
	private String name;

	@TestField
	ptivate int age;

	public void testFieldAnnotaion() {
		Field[] fields = this.getClass().getDeclaredFields();
		for (Field field : fields) {
            TestField anno = field.getAnnotation(TestField.class);
            if (null != anno) {
                //业务处理
                ...
            }
        }
	}
}

四、嵌套注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BaseAnno{
	boolean target() default false;
	boolean isDefault() default false;
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestNestingAnno{
	String name() default "";
	BaseAnno baseAnno() default @BaseAnno;
}

public class TestNestingField {
	@BaseAnno
	@TestNestingAnno(name = "test", baseAnno = @ BaseAnno(idDefault = true))
	String testField;
}

五、注解不支持继承
注解不能通过extends继承

六、使用apt处理注解
apt是sun为了帮助注解处理过程而提供的注解处理工具

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.CLASS) 
public @interface TestAptAnno{
	String name();
}


public class TestAptAnnoProcessor extends AbstractProcessor {

	// 初始化工作
    @Override
    public synchronized void init(ProcessingEnvironment env){ 
        super.init(env);
    }

	//处理逻辑,控制代码生成
    @Override
    public boolean process(Set<? extends TypeElement> annoations, RoundEnvironment env) { 
        ...
        return ture;
    }

	//支持的注解类型列表
    @Override
    public Set<String> getSupportedAnnotationTypes() { 
		Set<String> set = new HashSet<>();
        set.add(TestAptAnno.class.getCanonicalName());
        return set;
    }

	//支持的java版本信息
    @Override
    public SourceVersion getSupportedSourceVersion() {
      return SourceVersion.latestSupported();
   }
}
@TestAptAnno(name = "测试apt")
public class TestClass{
	public static void main(String[] args) {
		...	
	}
}

通过继承AbstractProcessor.java,可实现我们自己的注解处理器,在getSupportedAnnotationTypes() 方法中可指定注解的列表,在process()方法中,写我们自己的代码生成逻辑。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值