java註解學習筆記
一、jdk中的註解
jdk中都屬於編譯時註解,在編譯前就會提示錯誤,總共有兩種註解:
- @Deprecated 註解
表示方法已過時 - @Suppress Warning註解:忽略由Deprecated註解造成的警告
二、java第三方註解
這裏只列舉了Spring和Mybatis中常見的幾個
- Spring中的註解
- @Autowired註解
- @Service註解
- @Repository註解
- Mybatis中的註解
- @InsertProvider
- @UpdateProvider
- @Options
三、註解的分類
- 源碼註解
- 編譯時註解
- 運行時註解
- 元註解:給註解進行註解
- @Target(ElementType.XXXX)
作用:用於描述註解的使用範圍(即:被描述的註解可以用在什麼地方)
取值(ElementType)有:
1. CONSTRUCTOR:用於描述構造器
2. FIELD:用於描述域即類成員變量
3. LOCAL_VARIABLE:用於描述局部變量
4. METHOD:用於描述方法
5. PACKAGE:用於描述包
6. PARAMETER:用於描述參數
7. TYPE:用於描述類、接口(包括註解類型) 或enum聲明
最常用的TYPE(描述類)、METHOD(描述方法)、FIELD(描述成員變量) - @Retention(RetentionPolicy.RUNTIME)
- Inherited :是一個標記註解。
@Inherited闡述了某個被標註的類型是被繼承的。如果一個使用了@Inherited修飾的annotation類型被用於一個class,則這個annotation將被用於該class的子類。- Documented :是一個標記註解,表示可用於javadoc工具的文檔化
- @Target(ElementType.XXXX)
四、自定義註解
成員類型是受限的,合法的類型包括原始類型及String, Class, Annotation, Enumeration
同一個類文件只能被同一個類加載器對象加載一次
最簡化的註解定義:
@Target({ ElementType.TYPE}) //定義在類上的註解
@Retention(RetentionPolicy.RUNTIME) //運行時註解
@Inherited //可被繼承
@Documented //可用於文檔化
public @interface UdfAnnotation {
String value();
}
五、代碼實操
通過反射機制獲取由註解標記的信息並構建sql查詢語句
/**
* Person實體類,通過Table和Column註解標記表名和列明
*/
@Table("person")
public class Person {
@Column("id")
private String id;
@Column("name")
private String name;
@Column("age")
private Integer age;
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;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Column自定義註解
*/
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
public String value();
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Table自定義註解,用於標記表名
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
public String value();
}
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 測試類,用於從註解中獲取信息並構建sql語句
*/
public class Test {
public static void main(String[] args){
Person p1 = new Person();
p1.setId("1");
Person p2 = new Person();
p2.setName("kevin,lily");
Person p3 = new Person();
p3.setAge(10);
String q1 = query(p1);
String q2 = query(p2);
String q3 = query(p3);
System.out.println(q1);
System.out.println(q2);
System.out.println(q3);
}
public static String query(Object obj){
StringBuilder sql = new StringBuilder();
try {
Class c = Class.forName("com.example.demo.bases.reflect.project.Person");
if (c.isAnnotationPresent(Table.class)){
Table table = (Table)c.getAnnotation(Table.class);
String tableName = table.value();
//System.out.println(tableName);
sql.append("select * from ").append(tableName).append(" where 1=1");
Field[] fields = c.getDeclaredFields();
for(Field field : fields){
String columnName = ((Column)field.getAnnotation(Column.class)).value();
//System.out.println("列名:"+columnName);
// 得到方法名,並利用invoke通過方法名獲取到參數值
String methodName = "get"+columnName.substring(0,1).toUpperCase()+columnName.substring(1);
//System.out.println("方法名:"+methodName);
Method method = c.getDeclaredMethod(methodName);
Object mValue = method.invoke(obj);
//System.out.println("方法值:"+mValue);
if (mValue instanceof Integer){
sql.append(" and ").append(columnName).append("=").append(mValue);
}
if (mValue instanceof String){
if (((String) mValue).contains(",")){
String[] values = ((String)mValue).split(",");
for (String value : values){
sql.append(" and ").append(columnName).append("=").append("'").append(value).append("'");
}
}else{
sql.append(" and ").append(columnName).append("=").append("'").append(mValue).append("'");
}
}
}
}
}catch (Exception e){
e.printStackTrace();
}
return sql.toString();
}
}
運行結果: