注解
一、注解的概述
1.注解,或者叫做注释,英文单词是:Annotation
2.Annotation是一种引用数据类型,编译之后生成xxx.class 文件
二、注解的使用格式
1…怎么定义注解呢?语法格式?
[修饰符列表] @interface 注解类型名{}
2.注解怎么使用,用在什么地方?
第一:注解使用时的语法格式是;
@注解类型名
第二:注解可以出现在类上、属性上、方法上、变量上、注解还可以出现在注解类上 等…
3.自定义注解
// 自定义注解:Annotatiob
public @interface MyAnnotation {
// ???
}
自定义注解使用位置演示(默认情况下注解可以出现在容易位置)
@MyAnnotation
class Annotions{
@MyAnnotation
private int no;
@MyAnnotation
public Annotions() {
}
@MyAnnotation
public static void s1(){
}
@MyAnnotation
public void m2(){
}
}
三、JDK内置注解
1.java.lang包下的注释类型:
掌握:
Deprecated 用 @Deprecated 注释的程序元素,
不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。
用来注解,表示此方法已经过时
掌握:
Override 表示一个方法声明打算重写超类中的另一个方法声明。
只注解方法,这个注解是给编译器参考的,和运行阶段没有关系,凡是java中带有此注 解的编译器都会编译检查,如果这个方法不是重写父类的方法,编译器报错
不用掌握:
SuppressWarnings 指示应该在注释元素(以及包含在该注释元素中的
所有程序元素)中取消显示指定的编译器警告。
四、什么是元注解?
用来标注“注解类型”的“注解”,称为元注解。
1.常见的元注解有哪些?
Target
Retention
2.关于Target注解:
这是一个元注解,用来标注“注解类型”的“注解”
这个Target注解用来标注“被标注的注解”可以出现在哪些位置上。
@Target(ElementType.METHOD):表示“被标注的注解”只能出现在方法上。
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
表示该注解可以出现在:
构造方法上
字段上
局部变量上
方法上
....
类上...
3.关于Retention注解:
这是一个元注解,用来标注“注解类型”的“注解”
这个Retention注解用来标注“被标注的注解”最终保存在哪里。
@Retention(RetentionPolicy.SOURCE):表示该注解只被保留在java源文件中。
@Retention(RetentionPolicy.CLASS):表示该注解被保存在class文件中。
@Retention(RetentionPolicy.RUNTIME):表示该注解被保存在class文件中,并且可以被反射机制所读取。
五、自定义注解的注意事项
1.自定义的注解存在属性
// 自定义注解:Annotatiob
public @interface MyAnnotation {
// 我们通常在注解当中可以定义属性,以下这个是MyAnnotation的属性
// 看着像1一个方法,但是实际上我们称为属性name
String name();
}
当自定义的注解里面存在属性的时候,当使用注解修饰时,需要将注解进行赋值,否则会报错
@MyAnnotation // 报错
public void doSome(){
}
赋值的方式
@MyAnnotation(属性名字=属性值)
遇见给多个属性赋值的情况使用逗号隔开
@MyAnnotation(name="张")
public void doSome(){
}
2.属性指定默认值
public @interface MyAnnotation {
String name();
String color() default "str";
}
当注解指定默认值后,在使用注解的时候可以不写入属性的值
3.当属性是value的情况
public @interface MyAnnotation {
String value(); // 属性名字是value
}
当属性名字是value并且只有一个属性的话才可以省略,使用时可以不写属性名
@MyAnnotation("张")
public void doSome(){
}
4、注解当中属性的类型
属性的类型可以是:
byte, short,int, long,float,double,boolean,char,String,Class,枚举
以及以上的类型的数组形式
5.当自定义类型的数组的时候
public @interface MyAnnotation {
String value();
int [] index(); // 定义数组类型的属性
}
赋值使用方法
@MyAnnotation(value = "z",index = {1,2,3})
public void doSome(){
}
但是当数组里面只有一个属性的时候,大括号可以省略
6.当自定义类型是枚举类似的时候
// 自定义的注解
public @interface MyAnnotation {
meiju [] mmm();
}
// 枚举
enum meiju{
a,b,c,d
}
使用的时候就是数组里面保存的只可以是枚举里面的指定的数据
@MyAnnotation(mmm = {meiju.a,meiju.b,meiju.c,meiju.d})
public void doSome(){
}
同样数组里面只有一个元素是可以省略的
六、注解在开发中的应用
假设一个需求:
有一个叫做@id
这个注解只能够出现在类上面,当这个类上有这个注解的时候,要求这个类中必须有一个int类型的id属性,如果没有这个属性就报异常,如果有这个属性就正常执行.
定义注解:
// 表示这个注只可以作用在类上面
@Target(ElementType.TYPE)
// 该注解可以被反反射机制读取到
@Retention(RetentionPolicy.RUNTIME)
public @interface Id {
}
// 这个注解@Id 用来标注类,被标注的类中必须有一个int类型的id属性,没有就报异常
创建被注解修饰的类
@Id
public class user {
int id;
String name;
String password;
}
主方法
public static void main(String[] args) throws ClassNotFoundException {
// 通过反射获取类
Class userClass = Class.forName("javase.user");
// 判断类上是否存在id注解
if (userClass.isAnnotationPresent(Id.class)){
// 当一个类上面存在id注解的时候,要求类中必须存在int类型的id属性
// 如果没有int类型的id属性则报异常
// 获取类的属性
Field[] Files = userClass.getDeclaredFields();
boolean isok = false; // 给标记
for (Field field : Files){
if ("id".equals(field.getName()) && "int".equals(field.getType().getSimpleName())){
// 表示这个类是合法的类,有id且类型是int类型
isok = true; //表示合法
break;
}
}
// 判断是否合法
if (!isok){
System.out.println("被id注解标注的类中必须要有一个int类型的id属性");
}else {
System.out.println("合法");
}
}
}