zoukankan      html  css  js  c++  java
  • 注解



    1. 注解

    什么是注解(Annotation)?注解是放在Java源码的类、方法、字段、参数上的一种特殊“注释”,可以在编译、类加载、运行时被读取,并执行相对应的处理



    2. 基本注解

    • @Override:检查该方法实现父类方法
    • @Deprecated:过时注解
    • @SuppressWarnings:抑制编译器警告注解
    • @FunctionalInterface:函数式接口注解


    3. 自定义注解


    3.1 自定义定义注解

    标记注解,没有任何成员变量的注解,eg:@override

    public @interface MyAnnotation{
    }
    

    元数据注解,带有成员变量的注解,其中成员变量定义和方法类似,且只支持String、数组、Class、枚举、注解

    public @interface MyAnnotation {
    	int num() default 10;
    }
    

    3.2 使用自定义注解


    1. 给参数赋值

    public class FooClass {
    	
    	@MyAnnotation(num = 10)
    	public void foo(int num){
    		System.out.println("注解 + 反射的num为:" + num);
    	}
    }
    

    上面这样使用注解是没有任何作用的,那为什么我们使用@Controller就可以直接把该类改为控制器呢?因为框架为我们实现了这些功能,如果要自定义的注解也有功能,要配置反射技术来实现,下面举个栗子

    接着上面的代码

    public class FooClass {
    	
    	@MyAnnotation(num = 10)
    	public void foo(int num){
    		System.out.println("注解 + 反射的num为:" + num);
    	}
    
    	public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    		
    		// 获取类
    		Class fooClass = FooClass.class;
    		
    		// 获取类方法
    		for(Method method : fooClass.getMethods() ){
    			
    			// 获取方法上的注解
    			MyAnnotation myAnnotation =  method.getAnnotation(MyAnnotation.class);
    			if(myAnnotation != null){
    				
    				// 获取注解的元数据
    				int num = myAnnotation.num();
    				
    				// 获取对象实例
    				FooClass fClass = (FooClass) fooClass.newInstance();
    				method.invoke(fClass, num);
    			}
    		}
    	}
    }
    
    //输出
    注解 + 反射的num为:10
    

    注意要想使上面注解有效,必须在自定义注解上加上@Retention(RetentionPolicy.RUNTIME)


    @Retention

    • 这个注解是用来修饰注解的,用来指定被修饰的注解被保留多长时间
    • Java文件有三个时期:编译、class、运行,注解默认在class之后失效
    • 由于使用了反射,即运行期执行,要使自定义注解生效,必须加上@Retention(RetentionPolicy.RUNTIME),表示运行期该注解也生效

    2. 检查实例方法

    自定义注释

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Range {
    	int max() default 100;
    }
    

    定义一个User类

    public class User {
    	
    	@Range(max = 10)
    	public int age;
    
        @Range()
        public int age2;
    	
    	public int getAge() {
    		return age;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    }
    

    再定义一个方法

    public void check(User user) throws IllegalArgumentException, IllegalAccessException{
    
    	for(Field field : user.getClass().getFields()){
    		Range range = field.getAnnotation(Range.class);
    		if(range != null){
    			Object age = field.get(user);
    			if(age instanceof Integer){
    				int num = (int) age;
    				if(num > range.max()){
    					throw new IllegalArgumentException("年龄超过" + range.max());
    				}
    			}
    		}
    	}
    }
    

    测试

    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
    	
    	User user = new User();
    	user.setAge(11);
    	user.check(user);
    }
    

    输出

    Exception in thread "main" java.lang.IllegalArgumentException: 年龄超过10
    	at annotation.User.check(User.java:29)
        at annotation.User.main(User.java:43)
    


    4. 补充

    元注解用于修饰其他注解定义的


    4.1 @Retention

    用于指定被修饰的Annotation被保留多长时间,有SOURCE,CLASS,RUNTIME三个时期
    

    4.1 @Target

    它用于指定被修饰的Annotation用于修饰哪些程序单元,有:
    TYPE  类,接口
    FIELD  字段
    METHOD  方法
    PARAMETER  参数
    CONSTRUCTOR  构造方法
    LOCAL_VARIABLE  局部变量
    ANNOTATION_TYPE  注解
    PACKAGE
    

    4.2 @Inherited

    被修饰过的Annotation将具有继承性,即被修饰的类其子类也会有该注解的功能
    


  • 相关阅读:
    谷歌浏览器无法携带cookie问题
    如何言简意赅表达你需要寻求开发协助?
    vue传参params参数不能混用?
    浅谈JS变量声明和函数声明提升
    如何提高你的CSS水平
    闭包,看这一篇就够了——带你看透闭包的本质,百发百中
    Vue-给对象新增属性(使用Vue.$set())
    PHP const问题
    Linux/U-boot version with "-dirty"
    360度评估互评如何避免恶意打分
  • 原文地址:https://www.cnblogs.com/Howlet/p/12252541.html
Copyright © 2011-2022 走看看