Java 注解(Annotation)/java 标注;用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。
日常开发中新建Java类,我们使用class、interface比较多,而注解和它们一样,也是一种类的类型,他是用的修饰符为 @interface
。
注解的定义
**注释:**文字描述介绍程序,提供给程序员查看的帮助信息。
**注解:**也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释
。
概念描述:
1.5之后新特性
。解释说明程序。
。注解使用:@注解
。作用分类:
元数据/注解
生成文档【生成文档doc文档/java API】元数据/注解
对代码进行分析【使用反射】元数据/注解
让编译器能够实现基本的编译检查【Override】检查
该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法
时,会报编译错误
。
@Override
public String toString() {
return "AnnoTest{}";
}
标记
过时方法。如果使用该方法,会报编译警告
。如:Date
。
@Deprecated
public void test1(){
// 过时方法
Date d = new Date();
d.setYear(123);
}
指示编译器去忽略
注解中声明的警告。一般参数为:all
即就是 @SuppressWarnings("all")
。
@SuppressWarnings("all")
public void demo() {
Date d = new Date();
d.setYear(123);
}
@SuppressWarnings("all")
public class AnnoTest
@元注解
public @interface 注解名称{
属性;
}
在dos命令下编译
与反编译
。
public interface MyAnno extends java.lang.annotation.Annotation {
}
// 本质上就是一个接口默认继承Annotation
接口中定义的成员抽象方法。要求:
// 定义一周七天的枚举类型
public enum WeekDayEnum {
Mon, Tue, Wed, Thu, Fri, Sat, Sun, }
public static void main(String[] args) {
WeekDayEnum day = null;
switch (day) {
case Mon:
break;
case Mon2:
break;
}
}
描述注解的注解
@Target({
ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})// MyAnno3注解只能作用于类上
@Retention(RetentionPolicy.RUNTIME)// 保留到class字节码中,被JVM读取。
@Documented// 生成api文档
@Inherited// 会被继承
public @interface MyAnno3 {
}@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
分类:
@Target - 标记这个注解应该是哪种 Java 成员。
*ElementType:*TYPE 类上 METHOD 方法上 FIELD 子成员变量
@Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
RetentionPolicy:RUNTIME 会保留到class字节码中,被JVM读取。 CLASS 也会保留到class字节码中,但不被JVM读取。SOURCE
@Documented - 标记这些注解是否包含在用户文档api中。
@Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)。
获取注解中定义的属性值
/**
* 描述执行的类名和方法名
*/
@Target({
ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro {
String className();
String methodName();
}
/**
* public class ProImple implements Pro{
* String className(){
* return demo2.Demo1;
* }
* String methodName(){
* return test;
* }
* }
*/
反射注解
@Pro(className = "demo2.Demo1",methodName = "test")
public class ReflectTest {
public static void main(String[] args) throws Exception{
// 解析注解
// 1.获取字节码对象
Class<ReflectTest> rtc = ReflectTest.class;
// 2.获取注解
Pro annotation = rtc.getAnnotation(Pro.class);// 在内存中生成注解接口的子类实现对象
// 3.调用方法
String s = annotation.className();
String s1 = annotation.methodName();
System.out.println(s);
System.out.println(s1);
// 反射
Class<?> cls = Class.forName(s);// 加载class文件
Object obj = cls.newInstance();// 构造对象
Method method = cls.getMethod(s1);// 找到指定方法
method.invoke(obj);// 运行方法
}
}
Demo1
public class Demo1 {
public void test(){
System.out.println("Demo1...test...");
}
}
流程:
getAnnotation()
自定义注解
@Target({
ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Check {
}
测试对象
public class Calculator {
// +
@Check
public void add() {
String name = null;
System.out.println(name.equals(123));
System.out.println("1 + 0 =" + (1 + 0));
}
// -
@Check
public void sub() {
System.out.println("1 - 0 =" + (1 - 0));
}
// *
@Check
public void mul() {
System.out.println("1 × 0 =" + (1 * 0));
}
// /
@Check
public void div() {
System.