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)
