JAVA自定義註解的使用和定義
最近有所瞭解到自定義註解的應用,因此學習了一下,在專案後臺介面開發中,資料的傳輸經常有對資料內容格式及一些資訊規則的校驗,應用註解在資料進入後臺的開始使用自定義註解是一種比較可靠的方案。
一、註解的概念及分類
1.首先我們來看一下什麼是註解:
註解就是某種註解型別的一個例項,我們可以用它在某個類上進行標註,這樣編譯器在編譯我們的檔案時,會根據我們自己設定的方法來編譯類。
2.註解的分類
註解大體上分為三種:標記註解,一般註解,元註解,@Override用於標識,該方法是繼承自超類的。這樣,當超類的方法修改後,實現類就可以直接看到了。而@Deprecated註解,則是標識當前方法或者類已經不推薦使用,如果使用者還是要使用,會生成編譯的警告。
二、自定義註解
1.自定義註解的概念:
使用@interface自定義註解時,自動繼承了java.lang.annotation.Annotation介面,由編譯程式自動完成其他細節。在定義註解時,不能繼承其他的註解或介面。@interface用來宣告一個註解,其中的每一個方法實際上是聲明瞭一個配置引數。方法的名稱就是引數的名稱,返回值型別就是引數的型別(返回值型別只能是基本型別、Class、String、enum)。可以通過default來宣告引數的預設值。
定義註解格式:
public @interface 註解名 {定義體}
註解引數的可支援資料型別:
1.所有基本資料型別(int,float,boolean,byte,double,char,long,short)
2.String型別
3.Class型別
4.enum型別
5.Annotation型別
6.以上所有型別的陣列
Annotation型別裡面的引數該怎麼設定:
第一,只能用public或預設(default)這兩個訪問權修飾.例如,String value();這裡把方法設為defaul預設型別;
第二,引數成員只能用基本型別byte,short,char,int,long,float,double,boolean八種基本資料型別和 String,Enum,Class,annotations等資料型別,以及這一些型別的陣列.例如,String value();這裡的引數成員就為String;
第三,如果只有一個引數成員,最好把引數名稱設為"value",後加小括號.例:下面的例子FruitName註解就只有一個引數成員。
2.三個關鍵引數
*1、指示註釋型別的註釋要保留多久。如果註釋型別宣告中不存在 Retention 註釋,則保留策略預設為 RetentionPolicy.CLASS
*2、有三種取值(代表三個階段):
* RetentionPolicy.SOURCE:保留註解到java原始檔階段,例如Override、SuppressWarnings
* RetentionPolicy.CLASS:保留註解到class檔案階段,例如
* RetentionPolicy.RUNTIME:保留註解到執行時階段即記憶體中的位元組碼,例如Deprecated
*/
//元註解:表示的是註解的註解,(同義詞有元資訊、元資料)
//如果不加,javac會把這無用的註解丟掉
@Retention(RetentionPolicy.RUNTIME)
*3
三、程式碼示例
下面我們模擬一下[email protected]和@Table 註解的自定義
首先我們自定義兩個註解類:
[email protected]註解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by Tanyunlong on 2016/12/3.
* 資料庫表中 欄位 的註解對映
*/
@Target({ElementType.FIELD})//作用域是類或者介面
@Retention(RetentionPolicy.RUNTIME)//註解型別:執行時註解
public @interface Column {
String value();//註解只有一個變數時 變數名必須為value
}
[email protected]註解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by Tanyunlong on 2016/12/3.
* 資料庫名 @Table 對映註解
*/
@Target({ElementType.TYPE})//作用域是類或者介面
@Retention(RetentionPolicy.RUNTIME)//註解型別:執行時註解
public @interface Table {
String value();//註解只有一個變數時 變數名必須為value
}
3.定義表對映實體類
/**
* Created by Tanyunlong on 2016/12/3.
* 對映註解類
*/
@Table("user")
public class Filter {
@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;
@Column("email")
private String email;
@Column("mobile")
private String mobile;
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;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
4.解析註解類,編寫規則及測試類
import javafx.scene.control.Tab;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Objects;
/**
* Created by Tanyunlong on 2016/12/3.
*/
public class Test {
public static void main(String[] args){
Filter f1=new Filter();
f1.setId(10);
Filter f2=new Filter();
f2.setUserName("tanyunlong");
Filter f3=new Filter();
f3.setEmail("[email protected],[email protected]");
String sql1=query(f1);
String sql2=query(f1);
String sql3=query(f1);
}
public static String query(Filter filter){
StringBuffer sb=new StringBuffer();
//1.獲取到Class
Class c= filter.getClass();
//2.獲取到table的名字
boolean exists= c.isAnnotationPresent(Table.class);
if (!exists){
return null;
}
Table t=(Table)c.getAnnotation(Table.class);
String tableName= t.value();
sb.append("select * from").append(tableName).append("where 1=1");
//3.遍歷所有欄位
Field[] fArray=c.getDeclaredFields();
for (Field field:fArray){
/**
* 4.處理每個欄位對應的sql
* 拿到欄位名 欄位值 拼裝sql
*/
boolean fExists=field.isAnnotationPresent(Column.class);
if (!fExists){
continue;
}
Column column= field.getAnnotation(Column.class);
String columnName=column.value();//欄位名
String fieldName=field.getName();
String getMethodName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
Object fieldValue=null;
try {
Method getMethod=c.getMethod(getMethodName);
fieldValue=getMethod.invoke(filter);//欄位值
} catch (Exception e) {
e.printStackTrace();
}
//拼裝sql
if (fieldValue==null||(fieldValue instanceof Integer&&(Integer)fieldValue==0)){
continue;
}
sb.append("and").append(field).append("=").append(fieldValue);
}
System.out.println(sb.toString());
return sb.toString();
}
}