注解:
一、什么是注解:是元数据,即一种描述数据的数据。
语法格式:@注解类型名
注解可以出现在类上、属性上、方法(包括构造方法)上、参数上等。
注解可以出现在注解类型上。
注解的作用:主要功能就是起到一个标识作用。比如:Spring框架如果是基于注解开发,IOC主要负责解耦,核心容器只要存放实体Bean,但是这时spring框架不知道究竟要管理哪些实体Bean,然后就可以通过spring提供的注解来进行标识,spring会启动扫描器扫描当前工程所有的类,如果发现被扫描的类有spring提供的注解,然后该类就会装载进spring容器。
二、元注解:用来修饰注解的注解。
在定义注解时需要通过元注解指定被修饰注解的使用场合、是否生成文档、是否可以继承、注解保持的策略。
注解可以定义属性:包括所有基本数据类型,String,枚举
如果一个注解指定了属性,在使用此注解时,要给属性赋值!(除非已经赋予了默认值)。
如果属性有且仅有value,赋值时可以省略属性名。
public @interface MyAnnotation {
//在注解中定义属性 注意:不是方法
String value();
int age();
double num();
enum s{};
}
import com.jy.annotation.MyAnnotation;
@MyAnnotation(value = "key",age=12,num=3.14)
public class Demo01 {
public static void main(String[] args) {
}
}
default :注解中给属性赋予默认值的关键字。
public @interface MyAnnotation {
//在注解中定义属性 注意:不是方法
String value() default "key";
int age() default 12;
double num()default 3.14;
enum s{};
}
@MyAnnotation()
public class Demo01 {
public static void main(String[] args) {
}
}
三、案例:
需求:工程中如果实体Bean上有IdAnnotation注解修饰的话,在实体类中就必须含有私有的id属性,否则程序抛出异常
class.properties
classes = com.jy.pojo.Person;com.jy.pojo.User;
User类
package com.jy.pojo;
import com.jy.annotation.IdAnnotation;
@IdAnnotation
public class User {
private String name;
public User(String name) {
this.name = name;
}
public User() {
}
public String getName() {
int i;
return name;
}
public void setName(String name) {
this.name = name;
}
}
Person类
package com.jy.pojo;
import com.jy.annotation.IdAnnotation;
@IdAnnotation
public class Person {
private int id;
}
Demo
package com.jy.demo;
import com.jy.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;
public class Demo01 {
public static void main(String[] args) {
try {
FileReader fileReader = new FileReader("class");
Properties properties = new Properties();
properties.load(fileReader);
//获取所有实体bean的全类名
String classes = properties.getProperty("classes");
//将字符串通过分号切割
String[] split = classes.split(";");
for (String s : split) {
//获取字节码对象
Class aClass = Class.forName(s);
//获取注解,判断实体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 BeanIdNotFoundException("该类没有私有的id属性:"+aClass);
}
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
自定义异常:BeanIdNotFoundException
package com.jy.demo;
public class BeanIdNotFoundException extends RuntimeException{
public BeanIdNotFoundException(String message) {
super(message);
}
}
四、通过反射获取注解
Demo02
package com.jy.demo;
import com.jy.annotation.Filed;
import com.jy.annotation.IdAnnotation;
import com.jy.pojo.Person;
import java.lang.reflect.Field;
/**
* 通过反射获取注解(很重要,spring的IOC涉及这个操作)
*/
public class Demo02 {
public static void main(String[] args) throws Exception{
//获取字节码对象
Class<Person> personClass = Person.class;
//获取类上的注解
IdAnnotation annotation = personClass.getAnnotation(IdAnnotation.class);
//注解进行强转
IdAnnotation idAnnotation = (IdAnnotation)annotation;
//通过注解获取属性
String name = idAnnotation.name();
Field[] declaredFields = personClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
Filed annotation1 = declaredField.getAnnotation(Filed.class);
System.out.println(annotation1);
}
}
}
Filed:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Filed {
}
Person类
@IdAnnotation
public class Person {
@Filed
private int id;
@Filed
private int age;
@Filed
private String name;
}