Java注解含义:
Java注解,顾名思义,注解,就是对某一事物进行添加注释说明,会存放一些信息,这些信息可能对以后某个时段来说是很有用处的。
Java注解又叫java标注,java提供了一套机制,使得我们可以对方法、类、参数、包、域以及变量等添加标准(即附上某些信息)。且在以后某个时段通过反射将标注的信息提取出来以供使用。
样例(实现一个自己的注解):
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = {ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotaion {
String value();
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyFieldAnnotaion {
String value();
String type();
String lengths();
}
import java.io.Serializable;
@MyAnnotaion("student")
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
@MyFieldAnnotaion(value = "1",type = "int",lengths = "10")
String id;
@MyFieldAnnotaion(value = "蕾蕾",type = "String" ,lengths = "200")
String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}
import org.apache.poi.ss.formula.functions.T;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
/**
* 通过反射获取注解
*/
public class AnnotaionDemo {
public static void main(String[] args) throws Exception {
Class<T> clazz = (Class<T>) Class.forName("demo.knowledgepoints.annotation.Student");
//判断注解是否存在
if(clazz.isAnnotationPresent(MyAnnotaion.class)){
System.out.println("存在注解:MyAnnotaion");
}
//获取注解列表
Annotation[] annotaions = clazz.getAnnotations();
for (int i = 0; i < annotaions.length; i++) {
System.out.println("注解:"+annotaions[i]);
}
//获取注解内容
MyAnnotaion myAnnotaion = clazz.getAnnotation(MyAnnotaion.class) ;
System.out.println("注解的值为:"+myAnnotaion.value());
//获取方法上的注解内容
Field field = clazz.getDeclaredField("id");
//方法上注解是否存在
field.isAnnotationPresent(MyFieldAnnotaion.class);
//方法注解列表
field.getAnnotations();
//获取方法上的注解内容
MyFieldAnnotaion myFieldAnnotaion = field.getAnnotation(MyFieldAnnotaion.class);
System.out.println("value:"+myFieldAnnotaion.value()+"; type:"+myFieldAnnotaion.type()+"; lengths:"+myFieldAnnotaion.lengths());
}
}
运行结果:
根据这个案例:
1. 注解实现需要关键字:@interface;
2. 在注解上我们还使用了注解 @Target,@Retention。这些被称为元注解,
Java中元注解有四个: @Retention @Target @Document @Inherited;
@Retention:注解的保留位置
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target:注解的作用目标
@Target(ElementType.TYPE) //接口、类、枚举
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
3. 直接里面可以写方法:String value();
外部使用注解可以将值写入,后续可以拿到该值进行使用。
可以提供默认值: String value() default "花花";
修改 AnnotaionDemo 的方法实现一个常用功能,通过注解将值注入实体类中:
import org.apache.poi.ss.formula.functions.T;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 通过反射获取注解
*/
public class AnnotaionDemo {
public static void main(String[] args) throws Exception {
Student student = (Student) getbean("demo.knowledgepoints.annotation.Student");
System.out.println(student);
}
public static Object getbean(String className) throws Exception{
Class<T> clazz = (Class<T>) Class.forName(className);
//判断注解是否存在(该注解被当成标记使用)
if(!clazz.isAnnotationPresent(MyAnnotaion.class)){
throw new Exception("该类缺失注解“MyAnnotaion”,不能通过反射获取bean");
}
//创建实体类
Object object = clazz.newInstance();
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
//获取字段名
String name = fields[i].getName();
//过滤序列
if (name.equals("serialVersionUID")) {
continue;
}
//组装SET方法
Class<?> type = clazz.getDeclaredField(name).getType();
// 首字母大写
String replace = name.substring(0, 1).toUpperCase()
+ name.substring(1);
Method setMethod = clazz.getMethod("set" + replace, type);
//获取字段值
Field field = clazz.getDeclaredField(name);
MyFieldAnnotaion myFieldAnnotaion = field.getAnnotation(MyFieldAnnotaion.class);
String value = myFieldAnnotaion.value();
//执行set方法
if (value != null && !"".equals(value)) {
// ---判断读取数据的类型(判断部分类型)
if (type.isAssignableFrom(String.class)) {
setMethod.invoke(object, value);
} else if (type.isAssignableFrom(int.class)
|| type.isAssignableFrom(Integer.class)) {
setMethod.invoke(object, Integer.parseInt(value));
} else if (type.isAssignableFrom(Double.class)
|| type.isAssignableFrom(double.class)) {
setMethod.invoke(object, Double.parseDouble(value));
} else if (type.isAssignableFrom(Boolean.class)
|| type.isAssignableFrom(boolean.class)) {
setMethod.invoke(object, Boolean.parseBoolean(value));
}
}
}
return object;
}
}
运行结果:
案例中使用了反射:反射详解:https://www.cnblogs.com/jssj/p/11723910.html
总结语:注解功能在框架开发中被广泛使用:例如Spring,MyBatis等。注解的出现大大的减少了开发工作中的开发工作量。