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类型,但是一不小心,写成别的类,这个错误很不容易找到,那么这时,就需要用到注解@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的默认值是(etentionPolicy.SOURCE 源文件阶段)

@SuppressWarnings的默认值是(etentionPolicy.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([email protected]("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([email protected]("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、刚才所有类型的数组

通过看文档可以更好的了解注解,注解的应用已经越来越广泛,以后要注意此方面的应用

时间: 2024-10-12 13:51:55

Java关于注解的加深理解的相关文章

Java关于反射的加深理解

一.反射的基础 java程序中各个java类属于同一类事物,描述这类事物的java类名就是Class 比如说,很多人,用java来表示就用Person类,很多类,就用Class,Person类的实例对象比如张三.李四代表着一个个具体的人,而Class类就代表着各个类在内存中的字节码 一个类被类加载器加载进内存,会占用一片存储空间,这个空间的内容就是类的字节码,不同的类的字节码不同,所以他们在内存中的内容是不同,这些空间分别用一个一个对象来表示,这些对象具有相同的类型,这个类型就是Class 面试

[3] 注解(Annotation)-- 深入理解Java:注解(Annotation)--注解处理器

转载 http://www.cnblogs.com/peida/archive/2013/04/26/3038503.html 深入理解Java:注解(Annotation)--注解处理器 如果没有用来读取注解的方法和工作,那么注解也就不会比注释更有用处了.使用注解的过程中,很重要的一部分就是创建于使用注解处理器.Java SE5扩展了反射机制的API,以帮助程序员快速的构造自定义注解处理器. 注解处理器类库(java.lang.reflect.AnnotatedElement): Java使用

深入理解Java:注解

注解作用:每当你创建描述符性质的类或者接口时,一旦其中包含重复性的工作,就可以考虑使用注解来简化与自动化该过程. Java提供了四种元注解,专门负责新注解的创建工作.‘ 元注解 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明.Java5.0定义的元注解: [email protected], [email protected], [email protected], [email prote

深入理解Java:注解(Annotation)--注解处理器

深入理解Java:注解(Annotation)--注解处理器 如果没有用来读取注解的方法和工作,那么注解也就不会比注释更有用处了.使用注解的过程中,很重要的一部分就是创建于使用注解处理器.Java SE5扩展了反射机制的API,以帮助程序员快速的构造自定义注解处理器. 注解处理器类库(java.lang.reflect.AnnotatedElement): Java使用Annotation接口来代表程序元素前面的注解,该接口是所有Annotation类型的父接口.除此之外,Java在java.l

深入理解Java:注解(Annotation)自己定义注解入门

深入理解Java:注解(Annotation)自己定义注解入门 要深入学习注解.我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前.我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解: 元注解的作用就是负责注解其它注解. Java5.0定义了4个标准的meta-annotation类型.它们被用来提供对其它 annotation类型作说明.Java5.0定义的元注解: [email protected], [email protected], [email pro

[2]注解(Annotation)-- 深入理解Java:注解(Annotation)自定义注解入门

转载 http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 深入理解Java:注解(Annotation)自定义注解入门 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明.J

深入理解Java:注解(Annotation)基本概念

转自 竹子-博客:http://www.cnblogs.com/peida/archive/2013/04/23/3036035.html 什么是注解(Annotation): Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和着任何元数据(metadata)的途径和方法.Annotion(注解)是一个接口,程序可以通过反射来获取指定程序元素的Annotion对象,然后通过Annotion对象来获取注解里面的元数据. Annotation(注解)是JDK5.0及以后版

[1] 注解(Annotation)-- 深入理解Java:注解(Annotation)基本概念

转载 http://www.cnblogs.com/peida/archive/2013/04/23/3036035.html 深入理解Java:注解(Annotation)基本概念 什么是注解(Annotation): Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和着任何元数据(metadata)的途径和方法.Annotion(注解)是一个接口,程序可以通过反射来获取指定程序元素的Annotion对象,然后通过Annotion对象来获取注解里面的元数据. Ann

lombok 简化java代码注解 理解

lombok 注解: lombok 提供的注解不多,可以参考官方视频的讲解和官方文档.     Lombok 注解在线帮助文档:http://projectlombok.org/features/index.    下面介绍几个我常用的 lombok 注解:         @Data   :注解在类上:提供类所有属性的 getting 和 setting 方法,此外还提供了equals.canEqual.hashCode.toString 方法         @Setter:注解在属性上:为