廖雪峰java教程学习笔记——注解

什么是注解

用@…标记,实现额外的功能。类似python中的装饰器。就是一种装饰模式。

分类:

  1. SOURCE类型的注解主要由编译器使用
  2. CLASS类型的注解主要由底层工具库使用,涉及到class的加载
  3. RUNTIME类型的注解经常使用,还需要能手动编写。注意千万不要漏写@Retention(RetentionPolicy.RUNTIME),否则运行期无法读取到该注解。

使用注解的方式:

package oop_package.src.com.itranswarp.sample;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Main {
    public static void main(String[] args) throws ReflectiveOperationException {
        Person p = new Person();
        p.name = "abc";
        p.city = "shanghai";
        check(p);  //使用检查函数
        System.out.println(p.city);
    }
    
    //自定义注解逻辑功能
    static void check(Person person) throws IllegalArgumentException, ReflectiveOperationException {
        // 遍历所有Field:
        for (Field field : person.getClass().getFields()) {
            // 获取Field定义的@Range:
            Range range = field.getAnnotation(Range.class);
            // 如果@Range存在:
            if (range != null) {
                // 获取Field的值:
                Object value = field.get(person);
                // 如果值是String:
                if (value instanceof String) {
                    String s = (String) value;
                    // 判断值是否满足@Range的min/max:
                    if (s.length() < range.min() || s.length() > range.max()) {
                        throw new IllegalArgumentException("Invalid field: " + field.getName());
                    }
                }
            }
        }
    }
}

//定义注解
@Retention(RetentionPolicy.RUNTIME)  //运行期间可以使用
@Target(ElementType.FIELD)
@interface Range {
    int min() default 0;
    int max() default 255;
}

//使用注解
class Person {
    @Range(min=5, max=20)
    public String name;

    @Range(max=10)
    public String city;
}

通过@Range注解,配合check()方法,就可以完成Person实例的检查。

检查逻辑完全是自定义的,JVM不会自动给注解添加任何额外的逻辑。

例如,JUnit是一个测试框架,它会自动运行所有标记为@Test的方法。

定义注解 @interface

基本步骤:

  1. @interface定义;
  2. 添加参数、默认值,最常见的参数定义为value()
  3. 用元注解配置注解;
public @interface Report {
    int type() default 0;  //default设定默认值
    String level() default "info";
    String value() default "";
}

元注解 meta annotation

能注解其它注解。

@Target 定义注解能用在哪些位置

例如可用于方法:

@Target(ElementType.METHOD)
public @interface Report {
...
}

可用于方法和字段:

@Target({
    ElementType.METHOD,
    ElementType.FIELD
})
public @interface Report {
    ...
}

@Retention 定义注解生命周期

仅编译期:RetentionPolicy.SOURCE;
仅class文件:RetentionPolicy.CLASS;
运行期:RetentionPolicy.RUNTIME。

例如:

@Retention(RetentionPolicy.RUNTIME)
public @interface Report {
    int type() default 0;
    String level() default "info";
    String value() default "";
}

@Repeatable 注解可重复

@Repeatable
public @interface Report {
...
}

@Report(type=1, level="debug")
@Report(type=2, level="warning")
public class Hello {
}

@Inherited 子类是否可继承父类注解

@Inherited
@Target(ElementType.TYPE)
public @interface Report {
    int type() default 0;
    String level() default "info";
    String value() default "";
}

@Report(type=1)
public class Person {
}

public class Student extends Person {  //子类也具有@Report注解
}

reflect 注解

可以通过reflect查看一个类是否被注解过,获取注解等操作:

// 判断@Report是否存在于Person类:
Person.class.isAnnotationPresent(Report.class);
// 获取Person定义的@Report注解,若不存在则返回null
Report report = Person.class.getAnnotation(Report.class);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值