Java--註解
阿新 • • 發佈:2017-07-25
sel select get 賦值 cat 自動 ron style .com
一.註解的基本
1.註解的通俗理解
註解(Annotation) 為我們在代碼中添加信息提供了一種形式化的方法,是我們可以在稍後 某個時刻方便地使用這些數據(通過解析註解來使用這些數據)。
2.註解的作用
- 生成文檔
- 跟蹤代碼依賴性,實現替代配置文件功能,減少配置。如Spring中的一些註解
- 在編譯時進行格式檢查,[email protected]
- 每當你創建描述符性質的類或者接口時,一旦其中包含重復性的工作,就可以考慮使用註解來簡化與自動化該過程。
3.註解的狀態
源碼註解:只在源碼中存在的註解。
編譯時註解:註解在源碼和.class文件中都存在。
運行時註解:運行階段還起作用,甚至會影響運行邏輯的註解,如Spring, Mybatic中常用的註解。
4.註解的分類
a.jdk內置註解:
- @Override:表示當前的方法定義將覆蓋超類中的方法,如果出現錯誤,編譯器就會報錯。
- @Deprecated:如果使用此註解,編譯器會出現警告信息。
- @SuppressWarnings:忽略編譯器的警告信息。
如下Override的例子,其他方法自測,child繼承Person,並且覆蓋了Person中的方法:
public class child extends Person { @Override//覆蓋 publicint age() { // TODO Auto-generated method stub return 0; } @Override public String name() { // TODO Auto-generated method stub return null; } @Override public void sing() { // TODO Auto-generated method stub } }
b.元註解
註解的註解,常見的有4個,在自定義註解中會用到,分別是
@Target,@Retention,@Documented,@Inherited
c.自定義註解
自己定義的註解。自定義註解由元註解和自己定義的註解(annotation)構成,格式,要求及實例如下:
//自定義註解 //下面4行是元註解 @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.SOURCE)//元註解的作用域,生命周期 @Inherited //允許子繼承 @Documented//生成javadoc文檔時會包含次註解 //[email protected] public @interface Description{ /* * 成員類型是受限的,所有基本類型、String、Class、enum、Annotation、以上類型的數組形式。 * 如果註解只有一個成員時,則成員名必須取名為value(), * 在使用是可以忽略成員名和賦值名 * 註解類可以沒有成員,沒有成員的註解稱為標識註解 */ String value();//成員以無參無異常方式聲明 //String author(); //int age() default 18;//可以給成員指定默認的值 }
5.註解解析
註解解析其實是用了Java中的反射機制,不明白的可以看看我的上一篇博客,Java--反射的逐步理解
核心代碼如下:
//1.使用類加載器加載類 try { Class class1 =Class.forName("cn.ann.test.child");
//2.找到類上面的註解 boolean isExist=class1.isAnnotationPresent(Description.class);//判斷是否存在這個註解 Method[] ms = class1.getMethods(); for (Method method : ms) { boolean exist=method.isAnnotationPresent(Description.class); if(exist){ Description b=(Description)method.getAnnotation(Description.class); System.out.println(b.value()); } } if(isExist){ //3.得拿到註解實例 Description a=(Description)class1.getAnnotation(Description.class); System.out.println(a.value()); } //4.找到方法上的註解 for (Method method : ms) { Annotation[] s =method.getAnnotations(); for (Annotation annotation : s) { if(annotation instanceof Description){ System.out.println(((Description) annotation).value()); } } } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
二.註解應用的一個小場景
1.場景要求
a.有一張用戶表,字段包括用戶ID,用戶名,昵稱,年齡,所在城市
b.方便的對每個字段或著字段的組合條件進行檢索,並打印出SQL
2.實現方法
具體代碼如下(其中註釋了代碼的思路):
a.用戶表Users.java
@Table("user") public class Users { @Column("id") private int id; @Column("user_name") private String userName; @Column("nick_name") private String nickName; @Column("age") private int age; @Column("city") private String city; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
b.自定義註解Table.java
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Table { String value(); }
c.自定義註解Column.java
@Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Column { String value(); }
d.測試類test.java
public class Test { public static void main(String[] args) { Users f1 = new Users(); f1.setId(68);//表示查詢id為68的用戶 f1.setAge(35);
Users f2 = new Users(); f2.setUserName("huhu"); f2.setCity("lanzhou");
Users f3 = new Users(); f3.setAge(20);
String sql1 = query(f1); String sql2 = query(f2); String sql3 = query(f3);
System.out.println(sql1); System.out.println(sql2); System.out.println(sql3); } @SuppressWarnings("unchecked") public static String query(Object obj) { StringBuilder s=new StringBuilder(); //1.獲取到class Class class1 = obj.getClass(); //2.獲取到table的名字 boolean isExist = class1.isAnnotationPresent(Table.class); if(isExist){ Table hTable=(Table)class1.getAnnotation(Table.class); s.append("select * from ").append(hTable.value()).append(" where 1=1"); } //3.遍歷所有的字段 Field[] fields =class1.getDeclaredFields(); for (Field field : fields) { boolean exist = field.isAnnotationPresent(Column.class); if(exist){ Column f =(Column)field.getAnnotation(Column.class); String columnName = f.value(); //System.out.println(columnName); String fieldName = field.getName(); Object fieldString=null; String getMethodName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1); try { /* * 4.處理每個字段對應的sql * 4.1拿到字段名 * 4.2拿到字段的值 * 4.3拼裝sql */ Method aMethod = class1.getMethod(getMethodName); fieldString=(Object)aMethod.invoke(obj,null); //System.out.println(fieldString); if(fieldString==null||(fieldString instanceof Integer &&(Integer)fieldString==0)){ continue; } s.append(" and "+columnName); if(fieldString instanceof String){ s.append(" = "+"‘"+fieldString+"‘"); } else{ s.append(" = "+fieldString); } } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //Method[] msMethods = class1.getMethods(); //for (Method method : msMethods) { //method.invoke(class1, Object); //} return s.toString(); } }
三.一張圖描述註解
謝謝大家閱讀。
Java--註解