【java提高】(16)---java註解(Annotation)
阿新 • • 發佈:2019-06-04
java提高(16)---java註解
註解含義
註解是JDK1.5之後才有的新特性,它相當於一種標記,在程式中加入註解就等於為程式打上某種標記,之後又通過類的反射機制
來解析註解。
一、JDK自帶註解
JDK1.5之後內部提供的三個註解
@Deprecated #廢棄,過時。
@Override #重寫、覆蓋。
@SuppressWarnings #壓縮警告。
示例
@SuppressWarnings("deprecation") public class AnnotationTest { //4、這裡稱為壓縮警告註解,可以在類上也可以放在方法上,因為該方法用了個已經過期的方法.getYear(),所以會發出警告 //加上這個註解表明取消對deprecation的警告,那麼該方法裡有過時方法也不會發出預警。同時getYear()的那條橫線也消失了。 @SuppressWarnings("deprecation") public static void main(String[] args) { //1、這裡的.getYear()方法畫了一條橫線表示此方法已經過時了,裡面方法加上了@Deprecated註解 new Date().getYear(); } //2、這裡我通過@Deprecated註解自定義一個已經過時不建議使用的方法。 @Deprecated public String getName() { return "小小"; } //3、重寫(覆蓋)父類Object的toString()方法 @Override public String toString() { return "小小"; } }
註解示意圖
二、自定義註解
示例
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface AnCode {//使用@interface關鍵字定義註解
//如果只有一個屬性 強烈建議取名為value
String value() default "";
}
在自定義註解上面有四個註解,我們稱為元註解
,下面一個一個解釋。
1、@Target 用於描述註解的使用範圍
取值(ElementType)有: 1、CONSTRUCTOR: 用於描述構造器 2、FIELD: 用於描述域(欄位申明) 3、LOCAL_VARIABLE:用於描述區域性變數 4、METHOD: 用於描述方法 5、PACKAGE: 用於描述包 6、PARAMETER: 用於描述引數 7、TYPE: 用於描述類、介面(包括註解型別) 或enum宣告 8、TYPE_PARAMETER:輸入引數申明(JDK1.8) 9、TYPE_USE: 使用型別(JDK1.8)
2、@Retention 定義了該註解生命週期
取值(RetentionPoicy)有:
1、SOURCE: 在原始檔中有效(即原始檔保留)
2、CLASS: 在class檔案中有效(即class保留)
3、RUNTIME: 註解永久保留,可以被VM載入時載入到記憶體中
一般框架註解和我們自定義註解採用的幾乎都是RUNTIME
,因為只有這個才能執行時通過反射來獲取註解中的資料。
3、@Inherited
概念
: @Inherited闡述了某個被標註的型別是被繼承的。如果一個使用了@Inherited修飾的annotation型別被用於一個class,則這個annotation將被用於該class的子類。
注意
:@Inherited annotation型別是被標註過的class的子類所繼承。類並不從它所實現的介面繼承annotation,方法並不從它所過載的方法繼承annotation
解釋
: 比如A繼承B,B類的上面有一個註解@A帶有元註解@Inherited 那麼A也可以擁有B父類的這個註解@A,但介面實現是不可以的。同時需要指出@A註解是需要元註解@Retention(RetentionPolicy.RUNTIME)。
參考文章:java @Inherited註解的作用
4、@Documented
概念
:描述其它型別的annotation應該被作為被標註的程式成員的公共API,因此可以被例如javadoc此類的工具文件化。
5、自定義註解引數
1、只能用public或預設(default)這兩個訪問權修飾.例如,String value();這裡把方法設為defaul預設型別;
2、引數成員只能用基本型別byte,short,char,int,long,float,double,boolean八種基本資料型別和
String,Enum,Class,annotations等資料型別,以及這一些型別的陣列;
3、如果只有一個引數成員,最好把引數名稱設為"value",後加小括號(也可以不加小括號)
三、自定義註解案例
目標
實現一個簡單的通過註解生成SQL查詢語句。
先建立兩個註解
@Table表名註解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
//資料庫表名屬性
String value() default "";
}
@Column欄位名註解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
//資料庫表字段名稱和實體屬性對映
String value() default "";
}
User實體
@Table("t_user")
public class User {
/**
* 使用者Id
*/
@Column("user_id")
private Integer userId;
/**
* 使用者年齡
*/
@Column("age")
private Integer age;
public User(Integer userId, Integer age) {
this.userId = userId;
this.age = age;
}
//新增get和set方法
}
解析註解類
public class Query {
public static String query(Object object) throws Exception{
StringBuilder sql = new StringBuilder();
//1.利用反射獲取Class
Class c = object.getClass();
//2.獲取Table的名字
boolean isExist = c.isAnnotationPresent(Table.class);
if (!isExist) {
return null;
}
Table t = (Table) c.getAnnotation(Table.class);
//3、獲取註解上的value值
String tableName = t.value();
sql.append("select * form ").append(tableName).append(" where 1 = 1 ");
//4.遍歷所有的屬性欄位
Field[] fArray = c.getDeclaredFields();
for (Field field : fArray) {
//處理每個欄位對應的sql
boolean fExist = field.isAnnotationPresent(Column.class);
if (!fExist) {
continue;
}
Column column = field.getAnnotation(Column.class);
//資料庫欄位名
String columnName = column.value();
//5、將user_id 變成 userId
String[] columns = columnName.split("_");
StringBuilder columnBuilder = new StringBuilder();
for (int i = 0; i < columns.length; i++) {
String s = columns[i];
columnBuilder.append(s.substring(0, 1).toUpperCase()).append(s.substring(1));
}
//6、活動屬性值
String getMethodName = "get" + columnBuilder.toString(); //get方法名
Method getMethod = c.getMethod(getMethodName);
Object fieldValue = getMethod.invoke(object);//類欄位值
//7、拼裝sql
sql.append(" and ").append(columnName).append(" = ").append(fieldValue);
}
return sql.toString();
}
}
測試類
public static void main(String[] args) throws Exception {
User user = new User(001, 4);
String query = Query.query(user);
System.out.println("query = " + query);
}
執行結果
通過這個小案例實現了通過註解的方式,生成sql語句。
只要自己變優秀了,其他的事情才會跟著好起來(少將20)