java 註解分析及自定義註解
註解概念:
java提供了一種原程序中的元素關聯任何信息和任何元數據的途徑與方法。
註解分類:
運行機制分類:源碼註解,編譯時註解,運行時註解。
來源分類:JDK的註解,第三方註解,自定義註解。
自定義註解語法要求:
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description {
String name();
int age() default 18;
}
1.使用@interface關鍵字定義註解。
2.name()成員變量無參無異常。
3.可用default 為成員變量指定默認值
4.成員變量是受限的,合法的類型包括原始類型及String,Class,Annotation,Enumeration。
5.如果註解只有一個成員變量,則成員變量必須取名為value(),在使用時可以忽略成員變量名與賦值號(=)。
6.註解類可以沒有成員變量,沒成員變量的註解稱為標識註解。
元註解:
@Target(ElementType類型:CONSTURCTOR構造器方法聲明,FIELD字段聲明,LOCAL_VARI局部變量聲明,METHOD方法聲明,PACKGE包聲明,PARAMETER參數聲明,TYPE類接口聲明)
@Retention(RetentionPolicy類型:SOURCE只在源碼中顯示,編譯時丟失,CLASS編譯是記錄到class中,運行時忽略,RUNTIME運行時存在,可以通過反射讀取)
@Inherited允許子類繼承,解繼承只能是類的註解,接口不能繼承註解,方法上的註解也不可以被繼承。
@Documented生成javadoc文檔會生成註解
解析註解:
通過反射獲取類、函數或成員上的運行時註解信息,從而實現動態控制程序的運行邏輯。
自定義註解案例:自定義實現sql中的@Table與@Cloumm
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Table {
String value();
}
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Cloumm {
String value();
}
@Table("user")
public class User {
@Cloumm("id")
int id;
@Cloumm("name")
String name;
@Cloumm("age")
int age;
@Cloumm("email")
String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class UserTest {
public static void main(String[] args) {
User user = new User();
user.setId(10);
user.setName("zs");
user.setEmail("[email protected],[email protected],[email protected]");
query(user);
}
private static void query(User user) {
//1.獲取類加載器
Class c= user.getClass();
//2.獲取類上的註解
boolean isExist = c.isAnnotationPresent(Table.class);
StringBuffer sb =new StringBuffer();
if(isExist) {
Table table = (Table)c.getAnnotation(Table.class);
String tableName = table.value();
sb.append("select * from "+ tableName + " where 1=1");
}
//3.獲取所有字段
Field[] fields = c.getDeclaredFields();
for(Field f:fields) {
boolean fExist = f.isAnnotationPresent(Cloumm.class);
if(fExist) {
String tableName = f.getAnnotation(Cloumm.class).value();
//4獲取字段值
//4.1反射獲取字段方法
String fieldname = f.getName();
String methodName = "get"+fieldname.substring(0,1).toUpperCase()+fieldname.substring(1);
Object fieldValue = null;
try {
Method method = c.getMethod(methodName);
//4.2通過反射方法獲取字段值
fieldValue = method.invoke(user);
} catch (Exception e) {
e.printStackTrace();
}
//4.3拼裝sql
if(fieldValue==null || fieldValue instanceof Integer && (Integer)fieldValue == 0) {
continue;
}
if(fieldValue instanceof Integer) {
sb.append(" and "+tableName+" = "+fieldValue);
}
else if(fieldValue instanceof String){
if(((String) fieldValue).contains(",")) {
String[] values = ((String) fieldValue).split(",");
sb.append(" "+ tableName +" in (");
for(String v : values) {
sb.append("‘"+v+"‘,");
}
sb.deleteCharAt(sb.length()-1);
sb.append(")");
}else {
sb.append(" and "+tableName+" = ‘"+fieldValue+"‘");
}
}
System.out.println(sb.toString());
}
}
}
}
java 註解分析及自定義註解