一、JAVA自带的三种标准注解
1、@Override:此方法是重写父类的,如果非重写父类的方法,则会报错
2、@Deprecated:可以表明这种方法过时了,如果再使用会出现警告
3、@SuppressWarnings("value"):用该注解消除方法的警告
关键字 | 用途 |
deprecation | 使用了不赞成使用的类或方法时的警告 |
unchecked | 执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型。 |
fallthrough | 当 Switch 程序块直接通往下一种情况而没有 Break 时的警告。 |
path | 在类路径、源文件路径等中有不存在的路径时的警告。 |
serial | 当在可序列化的类上缺少 serialVersionUID 定义时的警告。 |
finally | 任何 finally 子句不能正常完成时的警告。 |
all | 关于以上所有情况的警告。 |
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * JAVA给予的三个标准注解 * 1、@Override:此方法是重写父类的,如果非重写父类的方法,则会报错 * 2、@Deprecated:可以表明这种方法过时了,如果再使用会出现警告 * 3、@SuppressWarnings:用该注解消除方法的警告 */ public class Main { @Deprecated public void test(){ } //取消警告的第一种写法:优点更方便 @SuppressWarnings("all") public void cat(){ List<?> list = new ArrayList<>(); } //取消警告的第二种写法:优点可以提供多种type @SuppressWarnings(value = {"all","unChecked"}) public void big(){ List<?> list = new ArrayList<>(); } }
二、创建注解
①、创建注解的四种元注解
@Target,表示该注解可以用什么地方。
如CONSTRUCTOR,构造器声明;FIELD,域声明;METHOD,方法声明;TYPE,类,接口或enum声明
@Retention,表示需要在什么级别保存该注解信息。
如SOURCE,注解将被编译器丢弃;CLASS,注解在class文件可用,但会被VM丢弃
RUNTIME,VM将在运行期间也保留注解,可以使用反射机制读取注解信息
@Documented,将此注解包含到Javadoc中。
@Inherited,允许子类继承父类的注解。
②、实例:创建注解
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//首先,该注解用在什么上,从ElementType获取类型Type @Target(ElementType.METHOD) //该注解可在什么时候存在,RetentionPolicy获取类型 @Retention(RetentionPolicy.RUNTIME) //构造注解的方法必须加上 @interface public @interface Test { //类似接口的创建,表示成员变量 id 为int 类型,且必须得赋值 public int id(); //表示创建成员变量name,如果没为name赋值则 用 default的值 public String name() default "NO"; }
注意事项:1、如果构造注解 2、构造注解的成员变量创建默认值与不创建默认值的区别
使用注解:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class Main { @Test(id=1) public void test(){ System.out.println("hello"); } @Test(id=2,name="asdas") public void to(){ System.out.println("world"); } }
③、创建注解的注意事项
1、默认值的创建:注解的方法必须需要默认值,若无默认值在实现的时候必须填写值
2、注解只支持基础引用类型(int、char、String等 特殊的:enum和Annotation)
④、注解的镶嵌
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Insert{ public String kick() default "Yes"; public String knock() default "No"; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public @interface Test { //类似接口的创建,表示成员变量 id 为int 类型,且必须得赋值 public int id(); //表示创建成员变量name,如果没为name赋值则 用 default的值 public Insert name() default @Insert; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@Test(id=2,name=@Insert) public void to(){ System.out.println("world"); }
三、创建注解处理器(反射机制)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * 原理: * 1、获取被注解标记的类,获取该类的所有方法 * 2、从方法中寻找注解的实例:通过method.getAnnotation()方法获取 * 3、获取注解实例之后,就可以调用注解的方法了。 */ public class UseTest { public static void main(String[] args){ Class<?> c = Annation.class; //通过反射获取所有方法 Method[] methods = c.getDeclaredMethods(); //判断该类是否存在方法 if (methods.length < 1){ return; } //遍历方法,获取方法的注解,获取注解实例 for(Method method : methods){ //从方法中,获取注解的实例 Test test = method.getAnnotation(Test.class); if (test != null){ //调用注解实例的方法 System.out.println(test.id()+" 回答是"+test.name()); } } } }