來源:http://blog.csdn.net/lifetragedy/article/details/7394910java
來看一個最簡單的annotation示例面試
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyAnnotation1 { String value(); }
上面這個MyAnnotation1.class文件包含一個值,下面來一個含有兩個值的annotation數據庫
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyAnnotation2 { String description(); boolean isAnnotation(); }
關鍵是來看這兩個自定義annotation的用法:數據結構
@MyAnnotation1("this isannotation1") public class AnnotationDemo { @MyAnnotation2(description = "this is annotation2", isAnnotation = true) public void sayHello() { System.out.println("hello world!"); } public static void main(String[] args) { new AnnotationDemo().sayHello(); } }
若是把@MyAnnotation1與@MyAnnotation2的位置換一換,會怎麼樣?
eclipse會報The annotation @MyAnnotation2 is disallowed for this locationeclipse
首先,網上的一些關於自定義annotation教程所舉的例子都不太好!this
就2個例子,而後一幫子人在那邊處處COPY這兩個例子而後處處轉發,搞得來你們雲裏霧裏一頭霧水, 同時一羣企業的面試官也就喜歡拿這個自定義annotation來做面試題,好像會個annotation就能給Senior software engineer了。.net
其實Annotation就是類反射加點枚舉,比個數據結構裏的冒泡排序還簡單,沒這麼誇張,關鍵是例子舉的很差,如今來看看下面這個例子。code
Hibernate的機制是可能經過JAVA類而後逆向成數據庫裏的某個表,你們還記得吧?
好比說Student.java文件,若是你這樣寫:blog
@Table(name="T_STUDENT") Public class Student{…}
表明這個類對應的數據庫表叫T_STUDENT排序
public class Student { private String id = ""; @Id(init = 1) public void setId(String id) { this.id = id; } }
就表明id這個field是一個主鍵,它的初始值爲1。
好了,如今開始咱們本身的例子,設有一CLASS叫Student,其中有三個fields:
private String name = ""; private int age = 0; private String studentId = "";
相應的每個field有一對的set, get方法
而後我在每一個set方法上造一個annotation叫ValueBind的註解,其做用是:
只要set方法上帶有ValueBind註解,它就會根據這個字段的類型把一個默認值,自動賦給Student類中相對應的field。
先來看一下Student類:
public class Student { private String name = ""; private int age = 0; private String studentId = ""; public String getName() { return name; } @ValueBind(type=fieldType.STRING, value="aa") public void setName(String name) { this.name = name; } public int getAge() { return age; } @ValueBind(type=fieldType.INT, value="11") public void setAge(int age) { this.age = age; } public String getStudentId() { return studentId; } @ValueBind(type=fieldType.STRING, value="1") public void setStudentId(String studentId) { this.studentId = studentId; } }
自定義一個ValueBind的Annotation,這個@ValueBoind就是個人自定義的annotation,裏面有兩個值,來看這個annotation是怎麼作的吧:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ValueBind { enum fieldType{ STRING, INT } fieldType type(); String value(); }
夠簡單的吧!
首先這個annotation只能被標註在方法上
其次它含有兩個值,一個是enum類型,一個是String類型
如今來看咱們真正的實現(用類反射來實現)
public class PersistStudent { public static void main(String[] args) throws Exception { Object c = Class.forName("annotation.Student").newInstance(); try { Method[] methodArray = c.getClass().getDeclaredMethods(); for (int i = 0; i < methodArray.length; i++) { if (methodArray[i].isAnnotationPresent(ValueBind.class)) { ValueBind annotation = methodArray[i].getAnnotation(ValueBind.class); String type = String.valueOf(annotation.type()); String value = annotation.value(); if (type.equals("INT")) { methodArray[i].invoke(c, new Object[] { new Integer(value) }); } else { methodArray[i].invoke(c, new Object[] { value }); } } } Student annotaedStudent = (Student) c; System.out.println("studentId====" + annotaedStudent.getStudentId() + " studentnName====" + annotaedStudent.getName() + " student Age====" + annotaedStudent.getAge()); } catch (Exception e) { throw new Exception(e); } } }
運行完畢後顯示:
studentId == 1 studentnName == aa student Age ==11
本身把代碼敲到eclipse裏後再去感覺一下吧,立刻讓你annotation入門