目录
1>@Target(这个注解用来标注“用来标记的注解”可以出现在哪些位置上)
2>@Retention(这个注解用来标注“用来标记的注解”最终保存的位置)
1、判断一个类上是否有该注解,并且通过反射机制获取这个注解和注解里的属性
2. 判断一个方法上是否有该注解,并且通过反射机制获取这个注解和注解里的属性
一、什么是注解?
1、概述
注解Anotation是一种引用类型。编译之后也是生成xxx.class文件
注解只是在编译阶段起作用,与运行期无关
2、怎么自定义一个注解?语法格式?
[修饰符列表] @interface 注解类型名{
}
public @interface myAnotation{
}
使用注解的语法格式是:@注解类型名
@myAnotation
public class Myclass{
@myAnotation
public String a;
@myAnotation
public void method(){
}
}
可以看出,注解可以出现在任意位置:类、属性、方法、变量、注解类型上......
3、自定义注解中可以定义属性
如果一个注解里有属性,则必须要给这个属性赋值 ,除非它有默认值
public @interface myAnotation{
//自定义一个属性name
String name();
//定义一个属性age
int age();
//定义一个属性color,默认值为“红色”
String color() default "红色";
}
public class Myclass{
//@ myAnotation //报错,如果一个注解里有属性,则必须要给这个属性赋值
//格式:@ myAnotation(属性名=属性值,属性名=属性值...)
@myAnotation(name="张三",age=10)//因为color有默认值,所以可以给color赋值,也可以不赋值
public void dosome(){
}
}
注意:
如果一个注解的属性的名字是value,并且该注解只有一个属性的话,在使用的时候,该属性名可以省略,代码演示如下:
public @interface myAnotation{
String value();
}
public class Myclass{
@myAnotation("abc")//因为属性的名字是value,且该注解只有这一个属性,所以属性名value可以省略
public void dosome(){
}
}
注解当中的属性可以是哪种类型?
byte short int long float double char boolean String Class 枚举类型
以及以上每一种的数组形式
【代码演示】
public @interface myAnotation{
String value1();
String[] value2();
int value3();
int[] value4();
}
public class Myclass{
@myAnotation(value1="abc",value2={"a","b"},value3=2,value4={1,2,3,4,5})
//属性是数组,用{}括起来表示
public void dosome(){
}
}
如果属性为枚举类型
例如有一个 枚举数组为 : public enum enum1{spring,summer}
public enum enum1{
spring,
summer
}
public @interface myAnotation{
enum1 value(); //属性为枚举类型
}
public class Myclass{
@myAnotation(enum1.spring) //因为属性名称为value,且注解只有一个属性,所以可以省略“value=”
//@myAnotation(enum1.spring,enum1.summer)
public void dosome(){
}
}
二、Java内置了哪些注解?
Java.lang包下的部分注释类型:
1.@Deprecated:表示被标记的元素已过时
这个注解主要是告诉其他程序员这个元素已过时,有更好的解决方案
@Deprecated //表示Myclass这个类已过时
public class Myclass{
@Deprecated //表示method这个方法已过时
public void method(){
}
}
2.@Override
1>只用来注解方法
2>凡是带@Override注解的方法,编译器都会进行检查,如果这个方法不是重写父类的方法,编译器会报错(可以用来检测方法名,属性有没有写错)。
public class Myclass{
@Override //表示method这个方法是重写父类的方法
public void method(){
}
}
三、元注解
1、什么是元注解?
用来标注“注解类型”的注解称为元注解
2、常见的元注解有哪些?
1>@Target(这个注解用来标注“用来标记的注解”可以出现在哪些位置上)
@Target(ElementType.METHOD) //表示@Override这个注解只能标记在方法上
public @interface Override{
}
@Target({ElementType.METHOD,ElementType.TYPE}) //表示@myAnotation这个注解只能出现在方法和类上
public @interface myAnotation{
}
@Target原码
//@Target源码
public @interface Target{
ElementType value(); //ElementType是一个枚举类型
}
ElementType是一个枚举类型
// ElementType源码
public enum ElementType{
Type,FIELD,METHOD,PATAMATER,CONSTRUCTOR, LOCAL_VARIABLE,
ANNOTATION_TYPE,PACKAGE,TYPE_PARAMETER,TYPE_USE,MODULE
}
2>@Retention(这个注解用来标注“用来标记的注解”最终保存的位置)
@Retention(RetentionPolicy.SOURCE) //@Override这个注解只被保存在Java源文件中
public @interface Override{
}
@Retention(RetentionPolicy.SOURCE) //这个注解只被保存在Java源文件中
@Retention(RetentionPolicy.CLASS) //这个注解被保存在class文件中
@Retention(RetentionPolicy.RUNTIME)//这个注解被保存在class文件中,并且可以被反射机制所读取
@Retention原码
//@Retention源码
public @interface Retention{
RetentionPolicy value();
}
RetentionPolicy是一个枚举类型
//RetentionPolicy源码
public enum RetentionPolicy{
SOURCE,CLASS,RUNTIME
}
public enum RetentionPolicy{SOURCE,CLASS,RUNTIME}
四、反射注解
要想能通过反射机制获取到该注解,则元注解@Retention里的参数一定是RetentionPolicy.RUNTIME,否则不能通过反射机制获取到该注解。
1、判断一个类上是否有该注解,并且通过反射机制获取这个注解和注解里的属性
@MyAnocation
public class MyAnocationTest{
}