注解
-
1、什么是注解
注解是元数据(Annotation),是一种对代码进行说明的数据,注解实际上相对于程序的一个标识,对于一个程序的解释说明注解也是一个引用数据类型,类加载的时候也会生成字节码文件。
-
2、注解在开发中的具体作用
注解最主要的功能就是起到一个标识作用,比如:使用Spring框架基于注解开发,IOC主要负责解耦,核心容器只要存放实体bean,但是此时Spring框架不知道究竟要管理哪些实体bean,然后就可以通过Spring提供的注解来进行标识,Spring会启动扫描器,扫描当前工程所有的类,如果发现被扫描的类有Spring提供的注解,然后该类就会装载进Spring容器!!!
通过注解能够实现的功能:编写文档:通过代码里标识的元数据生成文档;
代码分析:通过代码里标识的元数据对代码进行分析【使用反射】;
编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】
自定义注解
自定义注解可以用在方法(包括构造方法)、属性、类、参数上面
- 注解也可以指定属性:定义属性的类型 包括所有基本属性类型、String、枚举类型
- 如果给注解指定了属性,在修饰别的元素的时候,就必须要把这个属性赋值(除非在定义属性的时候已经赋予了默认值)
- default注解中给属性赋默认值的关键字
示例代码
public @interface MyAnnotation01 {
//在注解中定义属性 注意:不是方法
//如果属性名称是 value的话,那么该属性赋值的时候可以不用写属性名(前提注解只有value一个属性)
String value();
int age();
double salary() default 5000;
}
JDK内置注解
Java从1.5版本以后默认内置三个标注:
@Deprecated:建议程序员不要使用这样的元素,编译的时候会用产生警告信息,通常是因为它很危险或存在更好的选择,可以设定在程序里的所有的元素上。
@Override:只能用在方法之上的,表示一个方法声明打算重写超类的另一个方法声明。
@SuppressWarnings:指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。
元注解
元注解,就是定义注解的注解,也就是说这些元注解是的作用就是专门用来约束其它注解的注解。在定义注解时需要通过元注解指定例如注解的使用的场合、是否生成文档、是否可以继承、注解保持的策略。
元注解有:@Target,@Retention,@Documented,@Inherited
@Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括:
ElemenetType.CONSTRUCTOR 构造器声明
ElemenetType.FIELD 域声明(包括 enum 实例)
ElemenetType.LOCAL_VARIABLE 局部变量声明
ElemenetType.METHOD 方法声明
ElemenetType.PACKAGE 包声明
ElemenetType.PARAMETER 参数声明
ElemenetType.TYPE 类,接口(包括注解类型)或enum声明@Retention 表示在什么级别保存该注解信息。可选的 RetentionPolicy 参数包括:
RetentionPolicy.SOURCE 注解将被编译器丢弃
RetentionPolicy.CLASS 注解在class文件中可用,但会被JVM丢弃
RetentionPolicy.RUNTIME JVM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。@Documented 将此注解包含在 javadoc 中
@Inherited 允许子类继承父类中的注解
案例
如果实体bean上有@IdAnnotation注解修饰,在这个实体类中就必须含有私有id属性,否则程序抛出异常。
示例代码
package com.cs.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface IdAnnotation {
String name() default "张三";
}
package com.cs.pojo;
import com.cs.annotation.IdAnnotation;
@IdAnnotation
public class Person {
private int id;
private String name;
private double salary;
}
package com.cs.pojo;
import com.cs.annotation.IdAnnotation;
@IdAnnotation
public class Student {
private String name;
public Student(String name) {
this.name = name;
}
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
package com.cs.demo;
import com.cs.annotation.IdAnnotation;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Properties;
/**
* 需求:
* 在这个工程内,如果实体bean上有@IdAnnotation注解修饰,
* 在这个实体类中就必须含有私有id属性,否则程序抛出异常
*/
public class AnnotationDemo01 {
public static void main(String[] args) {
try {
//读取配置文件
FileReader fileReader = new FileReader("class.properties");
//创建集合对象
Properties properties = new Properties();
properties.load(fileReader);
//获取所有实体bean的全类名
String classes = properties.getProperty("classes");
//将字符串通过;来切割
String[] split = classes.split(";");
for (String sp : split) {
//获取字节码对象
Class aClass = Class.forName(sp);
//判断实体bean中是否有@IdAnnotation注解修饰
Annotation annotation = aClass.getAnnotation(IdAnnotation.class);
if (annotation != null){
//根据字节码对象获取属性
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
if (declaredField.getName().equals("id") && Modifier.toString(declaredField.getModifiers()).contains("private")){
System.out.println("该实体bean符合要求!!!! "+aClass);
}else {
throw new BeanNotFindIdException("该类没有私有的id属性!!!出现问题的类为"+aClass);
}
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class.properties配置文件
classes = com.cs.pojo.Person;com.cs.pojo.Student