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等。注解的出現大大的減少了開發工作中的開發工作量。