天天看点

自定义注解内置注解自定义注解元注解

文章目录

  • 内置注解
    • @Override
    • @Deprecated
    • @SuppressWarnings
  • 自定义注解
  • 元注解
    • @Target
      • ElementType.FIELD
      • ElementType.METHOD
      • ElementType.TYPE
      • ElementType.PARAMETER
    • @Retention
      • RetentionPolicy.RUNTIME
    • @Inherited
    • @Documented

内置注解

@Override

  • 用来标注方法是否是重写的父类的方法,如果不是重写的父类方法将会报异常

    创建一个Father类

public class Father {
	public void sleep() {
		System.out.println("FatherSleep");
	}
}
           
  • 创建一个Son类,并重写Father类中的sleep方法
public class Son extends Father {
	@Override
	public void sleep() {
		System.out.println("SonSleep");
	}
}
           

在这里Son类的sleep方法上加了@Override方法用来标识,Son类的方法重写了父类的sleep方法

如果给Son类添加一个新的,父类并没有的方法,再在上面加上@Override注解就会报错

public class Son extends Father {
	@Override
	public void sleep() {
		System.out.println("SonSleep");
	}
	
	@Override
	public void work() {
		System.out.println("SonWorks");
	}
}
           
  • work方法就会报错
异常信息:The method work() of type Son must override or implement a supertype method

@Deprecated

  • 说明所标注的成员变量或者方法已经过时(不推荐使用),如果使用编译器将会报警告信息

    给Father类的sleep方法上加@Deprecated注解

public class Father {
	@Deprecated
	public void sleep() {
		System.out.println("FatherSleep");
	}
}
           

加上@Deprecated之后

自定义注解内置注解自定义注解元注解

写一个测试类

public class AnnotationTest {
	@Test
	public void test1() {
		Father father = new Father();
		father.sleep();
	} 
}
           
自定义注解内置注解自定义注解元注解
自定义注解内置注解自定义注解元注解

虽然不影响执行程序结果,但是加上@Deprecated以说明该方法已经不推荐使用,在使用的时候eclipse会在该方法上显示中划线,并报出警告信息。

@SuppressWarnings

  • 忽略警告信息,加上@SuppressWarnings注解之后如果出现警告信息将会忽略,不再显示警告细腻。
  • 测试父类的sleep方法@Deprecated注解的作用的想要忽略警告信息,就可以加上@SuppressWarnings注解
    自定义注解内置注解自定义注解元注解
  • 加上@SuppressWarnings注解之后
自定义注解内置注解自定义注解元注解

@SuppressWarnings也可以加在类上或者成员变量上

自定义注解内置注解自定义注解元注解

自定义注解

  • 自定义注解结构
[public] @interface 注解名 {
	[属性1;]
	[属性2;]
	...
	[属性n;]
}
           

属性结构

注意:

  1. 注解属性默认没有默认值,如果注解中定义了无默认值的注解属性,则使用该注解时必须给属性指定值,否则会报错。
  2. 如果注解的属性名为vale可以直接赋值。
  3. 如果注解的属性是一个数组,但是该数组只有一个元素,则可以把{}省略,如果超过一个则需要加上{}

定义一个注解@MyAnnotation

public @interface MyAnnotation {
	String value() default "";
}
           

元注解

  • Java提供了四个用于修饰自定义注解的元注解:@Target、@Retention 、@Documented和@Inherited

@Target

  • @Target:用于限定被修饰的自定义注解修饰的元素类型,该元注解属性有
    1. ElementType.ANNOTATION_TYPE:应用于其他注解的元注解
      2. ElementType.CONSTRUCTOR:应用于构造函数
      3. ElementType.FIELD:应用于全局属性
      4. ElementType.LOCAL_VARIABLE:应用于方法中的本地变量
      5. ElementType.METHOD:应用于方法
      6. ElementType.PACKAGE:应用于包
      7. ElementType.PARAMETER:应用于方法的参数
      8. ElementType.TYPE:应用于类、接口或者枚举声明
               

常用的属性有ElementType.FIELD、ElementType.METHOD、ElementType.PARAMETER、ElementType.TYPE

ElementType.FIELD

  • 应用于成员变量的属性
@Target(ElementType.FIELD)
public @interface MyAnnotation {
	String value() default "";
}
           

这时候自定义注解只能用在成员变量上,用在其他的地方将会报错

public class Father {
	@MyAnnotation
	int age;
	public void sleep() {
		System.out.println("FatherSleep");
	}
}
           

ElementType.METHOD

  • 应用于普通方法的属性
@Target(ElementType.METHOD)
public @interface MyAnnotation {
	String value() default "";
}
           
自定义注解内置注解自定义注解元注解
  • 把自定义注解放在方法上面之后不会出现错误了
自定义注解内置注解自定义注解元注解

ElementType.TYPE

  • 应用于类、接口或者枚举声明
@Target(ElementType.TYPE)
public @interface MyAnnotation {
	String value() default "";
}
           

这时如果注解加在方法上面就会报错

自定义注解内置注解自定义注解元注解

把这个注解加载类上面,就不会报错了

自定义注解内置注解自定义注解元注解

ElementType.PARAMETER

  • 应用于方法的参数
@Target(ElementType.PARAMETER)
public @interface MyAnnotation {
	String value() default "";
}
           

着中国自定义注解的使用

public class Father {
	int age;
	public void sleep() {
		System.out.println("FatherSleep");
	}
	public void sleep(@MyAnnotation String name) {
		System.out.println("FatherSleep");
	}
}
           

@Retention

  • @Retention:指定被修饰的自定义注解可以保留多久,该元注解有属性值如下
    1. RetentionPolicy.SOURCE:编译器将直接丢弃被修饰的注解。
      2. RetentionPolicy.CLASS:默认值,编译器将把注解记录在class文件中,当运行Java程序时,虚拟机不再保留注解;
      3. RetentionPolicy.RUNTIME:编译器将把注解记录在class文件中,当运行java程序时,虚拟机保留注解,程序可以通过反射获取该注解;
               

常用的属性为

RetentionPolicy.RUNTIME

public @interface MyAnnotation {
	String value() default "";
}
           

运行测试类

@Test
	public void test2() {
		Class clazz = Father.class;
		Annotation[] annotations = clazz.getAnnotations();
		for (Annotation annotation : annotations) {
			System.out.println(annotation);
		}
	}
           

运行结果没有输出该类的注解

  • 添加@Retention(RetentionPolicy.RUNTIME)元注解
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	String value() default "";
}
           
自定义注解内置注解自定义注解元注解

@Inherited

  • @Inherited:如果父类所使用的注解有@Inherited修饰,则子类可以继承该注解,否则不能继承。

    直接运行测试中的测试方法

@Test
	public void test2() {
		Class clazz = Son.class;
		Annotation[] annotations = clazz.getAnnotations();
		for (Annotation annotation : annotations) {
			System.out.println(annotation);
		}
	}
           

没有输出

给自定义注解加上@Inherited元注解

@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
	String value() default "";
}
           

再次运行测试方法,控制台上可以输出该类的子类的注解

自定义注解内置注解自定义注解元注解

@Documented

  • @Documented:执行javadoc命令时,被该元注解修饰的自定义注解也会生成在文档中

    不加该注解将不会在生成的文档中出现自定义的注解

    自定义注解内置注解自定义注解元注解
  • 加上该注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
	String value() default "";
}
           

生成的文档就会有该类的注解

自定义注解内置注解自定义注解元注解