注解:说明程序得,给计算机看的java
注释:用文字描述程序,给程序员看的程序员
// 单行注释 /* 多行注释 */ /** 文档注释 */
注解的定义:api
注解(Annotation),也叫元数据。一种代码级别的说明。它是 JDK1.5 及之后版本引入的一个特性,与类、接口、枚举是在同一个层次。它能够声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。数组
做用分类:ide
一、编写文档:经过代码里标识的注解生成文档【生成文档doc文档】spa
二、编译检查:经过代码里标识的注解让编译器可以实现基本的编译检查【Override】code
三、代码分析:经过代码里标识的注解对代码进行分析【使用反射】对象
@Override 检查方法是否继承父类或接口继承
@@Deprecated 该注解表示注释的内容过期接口
@@SuppressWarnings 压制警告
@SuppressWarnings("all") public class AnnoDemo { @Override public String toString() { return "Demo01{}"; } @Deprecated public void show(){ //发现过期了,功能跟不上需求了 } public void showNew(){ //知足功能更增强大的方法 } public void demo(){ show(); //不推荐使用,但可使用 showNew(); Date date = new Date(); date.getYear();//不推荐使用,但可使用 } }
格式
//元注解 public @interface MyAnno{ //属性列表 }
反编译
javap AnnoName.class
public interface MyAnno extends java.lang.annotation.Annotation { }
注解的本质其实就是一个接口,继承Annotation父接口
/** * 注解的本质就是接口 */ public @interface MyAnno { public String show(); }
属性,在接口中定义的抽象方法
public @interface MyAnno { String Show1(); int show2(); String[] show3(); AnnoName show4(); PersonEnum show5(); }
一、基本数据类型
二、String 类型
三、枚举类型
四、注解
五、以上类型的数组
public @interface MyAnno { String show1(); int show2(); String[] show3(); AnnoName show4(); PersonEnum show5(); }
默认值
若是定义的属性时,使用default关键字给属性默认初始值,能够在使用注解是不赋值
public @interface MyAnno { String name(); int age() ; } public class Demo01 { @MyAnno(name="andy",age = 18) public void show(){ } }
public @interface MyAnno { String name(); int age() default 18; } public class Demo { @MyAnno(name="andy") public void show(){ } }
value
若是只有一个属性须要赋值,并且该属性的名称是
value
,那么在赋值时value
能够省略
public @interface MyAnno { String value(); } public class Demo { @MyAnno("andy") public void show(){ } }
{}
数组赋值的时候,值使用
{}
包裹,若是数组中只有一个值,那么{}
能够省略
public @interface MyAnno { String show1(); String[] show2();//数组一个值的时候能够省略大括号 AnnoName show3(); PersonEnum show4(); } public class Demo01 { @MyAnno(show1="Andy",show3 = @AnnoName,show4 = PersonEnum.P1,show2 = {"a","b"}) public void show(){ } }
JDK 中给咱们提供的4个元注解
描述当前注解可以做用的位置
一、ElementType.TYPE,能够做用在类上
二、ElementType.METHOD,能够做用在方法上
三、ElementType.FIELD,能够做用在成员变量上
@Target({ElementType.TYPE, ElementType.METHOD,ElementType.FIELD}) public @interface MyAnno { } @MyAnno public class Worker { @MyAnno private String name; @MyAnno public void show(){ } }
描述注解被保留到的阶段
SOURCE < CLASS < RUNTIME
一、SOURCE,表示当前注解只在代码阶段有效
二、CLASS,表示该注解会被保留到字节码阶段
三、RUNTIME,表示该注解会被保留到运行阶段 JVM
//自定义的注解,通常用RUNTIME @Retention(RetentionPolicy.RUNTIME) public @interface MyAnno { }
描述注解是否被抽取到 JavaDoc api中
描述注解是否能够被子类继承
public class Teacher { public void show(){ System.out.println("Teacher show ...."); } } public class Student { public void show(){ System.out.println("student show ...."); } }
/** * 自定义注解 * 该注解标明要执行哪一个类中哪一个方法 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface InvokAnno { String className(); String methodName(); }
@InvokAnno(className = "com.andy.anno.Student",methodName = "show") public class MyMain { public static void main(String[] args) throws Exception { //获取类对象 Class<MyMain> clazz = MyMain.class; //获取类对象中的注解 InvokAnno annotation = clazz.getAnnotation(InvokAnno.class); /* 注解本质是 接口 获取到的其实时接口的实现 public class MyInvokAnno implements InvokAnno{ String className(){ return "com.andy.anno.student"; } String methodName(){ return "show"; } } */ //获取注解中对应的属性 String className = annotation.className(); String methodName = annotation.methodName(); System.out.println(className+" "+methodName); //经过反射的方式实现接口的功能 Class<?> aClass = Class.forName(className); Method show = aClass.getDeclaredMethod("show"); Object o = aClass.newInstance(); show.invoke(o); } }