zoukankan      html  css  js  c++  java
  • Java加深理解有关注释


    一、获取应用笔记

    常常会遇到这种情况

    package Tokyo.Hot;
    public class Demo {
    	
    	public static void main(String[] args) {
    		
    		new Thread().stop();
    		//画一条线。非常明显是过时的方法
    	}
    }
    这是过时的方法。这时就要用到注解。告诉编译器,我知道这是过时的,我就喜欢用


    @SuppressWarnings("deprecation")   deprecation。过时的,背单词
    
    package Tokyo.Hot;
    
    public class Demo {
    	
    	@SuppressWarnings("deprecation")
    	public static void main(String[] args) {
    		
    		new Thread().stop();
    	
    	}
    }

    注意:一个注解就是一个类

    当你曾经写好了一个类的方法,可是如今不想用了。为了不给用这种方法的人造成困扰,那么就能够在方法上加入一个@Deprecated,这是

    一个过时的方法

    public class Demo {
    
    	public static void main(String[] args) {
    
    		Out();
    	}
    	@Deprecated
    	private static void Out() {
    		System.out.println("Hello,World!");
    	}
    }

    HashSet,须要复写equals方法,可是equals(),參数是Object类型。可是一不小心,写成别的类,这个错误非常不easy找到,那么这时,就须要用到注解@Override,复写

    new Thread(new Runnable() {
    					@Override
    					public int run() {
    					}}).start();

    注解,相当于一种标记,在包、类、方法、变量、字段等上面加入了这样的标记,告诉编译器。你依照我的标记採取对应的动作


    OK。注解的皮毛。已然了解!

    二、注解的定义和反射调用

    我们想使用某个类,那么就必须先设计写好那个类,注解也是如此,我们想使用某个注解,那么我们也必须提前先设计写好那个注解

    1.定义注解类:

    public @interface MyTokyo {} 和定义接口的方式是一样的


    2.应用了注解的类: 
    @MyTokyo
    class MyClass{},检查这个类上是否有这个注解

    3.对"应用注解的类"进行反射
    要对一个类进行检查,肯定用到反射

    @MyTokyo
    public class Demo {
    
    	public static void main(String[] args) {
    		Boolean flag = Demo.class.isAnnotationPresent(MyTokyo.class);//检查是否有注解
    		if(flag){
    			MyTokyo myTokyo = (MyTokyo) Demo.class.getAnnotation(MyTokyo.class);//得到这个注解对象
    			System.out.println(myTokyo);
    		}
    	}
    }

    会发现什么也不打印
    在自己定义的注解上加入注解,注解的注解->源注解

    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyTokyo {}

    @Retention(RetentionPolicy.RUNTIME)的意义,也就是告诉编译器,将自己定义的注解保留到执行期。由于自己定义的注解可能在编译期,就清除了。javac把源文件编译成class,可能就把源程序的注解就去掉了。还有可能是在类载入器把类载入到内存时,类中的注解是否保留,
    也是问题。

    特别注意:class文件里的东西。不是字节码,仅仅有类载入器把class文件进行安全检查等一系列的处理后。载入到内存的二进制才是字节码

    一个注解的生命周期有三个阶段:
    1.java源文件  2.class文件  3.内存中的字节码

    所以@Retention就有三种取值:

    (RetentionPolicy.SOURCE 源文件阶段)

    (RetentionPolicy.CLASS class文件阶段)

    (RetentionPolicy.RUNTIME 执行阶段)

    而默认值是CLASS阶段

    @Override的默认值是(RetentionPolicy.SOURCE 源文件阶段)

    @SuppressWarnings的默认值是(RetentionPolicy.SOURCE 源文件阶段)

    @Deprecated的默认值 (RetentionPolicy.RUNTIME 执行阶段)


    继续,在自己主动注解上再加一个注解@Target

    @Retention(RetentionPolicy.SOURCE)


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

    作用:告诉编译器,自己定义的注解仅仅能载入方法上

    要想使注解在类和方法都能使用
    @Retention(RetentionPolicy.SOURCE)

    @Target({ElementType.METHOD,ElementType.TYPE})

    public @interface MyTokyo {}


    注意是TYPE,类型。不不过class,接口都能够,所以用TYPE更贴切,而不用class


    三、为注解添加属性


    注解之所以强大,是由于其的属性

    注解非常像接口,而注解的属性就非常像方法

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD,ElementType.TYPE})
    
    public @interface MyTokyo {
    	String color();//注解有个属性color,返回字符串
    }

    那么主函数就能够是设置属性值

    @MyTokyo(color="red")
    
    public class Demo {
    	
    	public static void main(String[] args) {
    		Boolean flag = Demo.class.isAnnotationPresent(MyTokyo.class);//检查是否有注解
    		if(flag){
    			MyTokyo myTokyo = (MyTokyo) Demo.class.getAnnotation(MyTokyo.class);//得到这个注解对象
    			System.out.println(myTokyo.color());
    		}
    	}
    }

    打印red,这就是为注解加入属性,在用的时候,给它设置属性值

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD,ElementType.TYPE})
    
    public @interface MyTokyo {
    	String color() default "blue";//默认是blue
    	String value();
    }
    
    
    @MyTokyo(color="red",value="ax")//属性没有设置默认的时候。全部属性必须都要写
    
    public class Demo {
    	@MyTokyo("xc")//由于color设置了缺省值,所以能够仅仅写xc代表value的属性值。能够不写value
    	public static void main(String[] args) {
    		Boolean flag = Demo.class.isAnnotationPresent(MyTokyo.class);//检查是否有注解
    		if(flag){
    			MyTokyo myTokyo = (MyTokyo) Demo.class.getAnnotation(MyTokyo.class);//得到这个注解对象
    			System.out.println(myTokyo.color());
    		}
    	}
    }

    数组类型的属性

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD,ElementType.TYPE})
    
    public @interface MyTokyo {
    	String color() default "blue";
    	String value();
    	int[] arr() default {3,4,5}; 
    }

    注意数组的元素假设仅仅有一个的话,arr=1。能够不写大括号

    @MyTokyo(color="red",value="ax",arr={1,2,3,4})
    
    public class Demo {
    	@MyTokyo("xc")
    	public static void main(String[] args) {
    		Boolean flag = Demo.class.isAnnotationPresent(MyTokyo.class);
    		if(flag){
    			MyTokyo myTokyo = (MyTokyo) Demo.class.getAnnotation(MyTokyo.class);//得到这个注解对象
    			System.out.println(myTokyo.color());
    			System.out.println(myTokyo.value());
    			System.out.println(myTokyo.arr().length);
    		}
    	}
    }

    枚举类型的属性

    //定义一个枚举类

    public class Week {
    	private Week(){}
    	public final static Week SUN = new Week();
    	public final static Week MON = new Week();
    	public Week nextDay(){
    		return this==SUN? MON : null;
    	}
    	public String toString(){
    		return this==MON ? "MON":"SUN";
    	}
    	public enum WeekDay{
    		SUN,MON;
    	}
    }

    定义枚举类型的属性

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD,ElementType.TYPE})
    
    public @interface MyTokyo {
    	String color() default "blue";
    	String value();
    	Week.WeekDay Day() default Week.WeekDay.SUN;//定义枚举类型的属性
    	int[] arr() default {3,4,5}; 
    	MyAnotaion2 anotaionArr() default @MyAnotaion2("x");
    }
    
    @MyTokyo(anotaionArr=@MyAnotaion2("wjw"),color="red",value="ax",arr={1,2,3,4})
    
    public class Demo {
    	@MyTokyo(value="xc",Day=Week.WeekDay.SUN)
    	public static void main(String[] args) {
    		Boolean flag = Demo.class.isAnnotationPresent(MyTokyo.class);
    		if(flag){
    			MyTokyo myTokyo = (MyTokyo) Demo.class.getAnnotation(MyTokyo.class);//得到这个注解对象
    			
    			System.out.println(myTokyo.Day().name());
    		}
    		
    	}
    }

    注解类型的属性
    public @interface MyAnotaion2 {
    	String value();
    }
    
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD,ElementType.TYPE})
    
    public @interface MyTokyo {
    	String color() default "blue";
    	String value();
    	int[] arr() default {3,4,5}; 
    	MyAnotaion2 anotaionArr() default @MyAnotaion2("x");//返回一个MyAnotaion2注解的注解类型属性
    }

    注解中的注解类型属性

    @MyTokyo(anotaionArr=@MyAnotaion2("wjw"),color="red",value="ax",arr={1,2,3,4})
    
    public class Demo {
    	@MyTokyo("xc")
    	public static void main(String[] args) {
    		Boolean flag = Demo.class.isAnnotationPresent(MyTokyo.class);
    		if(flag){
    			MyTokyo myTokyo = (MyTokyo) Demo.class.getAnnotation(MyTokyo.class);//得到这个注解对象
    			System.out.println(myTokyo.color());
    			System.out.println(myTokyo.value());
    			System.out.println(myTokyo.arr().length);
    			System.out.println(myTokyo.anotaionArr().value());
    		}
    	}
    }

    注解的属性返回值还能够是8个基本类类型、class、所有类型的只是阵列
    通过查看文件,以便更好地了解的注释。Notes应用也越来越广泛,以后要注意这个应用方面


  • 相关阅读:
    python服务注册到nacos
    springboot设置响应状态码
    nio 实现群聊小系统
    记一次maven问题(把maven仓库打包后在离线环境另一个机器导入不成功)
    客户端查看sql的执行时间
    java 运行python脚本
    http访问支持websocket
    ”真实项目“ 与“作业”
    工厂方法模式
    idea 开发 SSM jar包找不到
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5033936.html
Copyright © 2011-2022 走看看