文檔版本 | 開發工具 | 測試平臺 | 工程名字 | 日期 | 作者 | 備註 |
---|---|---|---|---|---|---|
V1.0 | 2016.06.16 | lutianfei | none |
註解
什麼是註解,它有什麼作用?
@xxx
就是一個註解。
註釋:它是用於描述當前代碼功能,是給程序員使用的。
註解:它是描述程序如果運行,是給
編譯器
,解釋器
,jvm
使用。jdk中自帶三個註解
1.
@Override
:是給編譯器使用,用於描述當前的方法是一個重寫的方法。- 注意:在jdk1.5與jdk1.6中有區別
- jdk1.5中@Override它只能描述繼承中的重寫.
- jdk1.6中@Override它不僅能描述繼承中的重寫,還可以描述實現中的重寫
2.
@Deprecated
: 用於描述方法過時。方法什麼時候過時?
- 1.有新的版本的方法替換舊版本方法。
- 2.在舊的版本中存在安全隱患的方法
3.`@SuppressWarning : 去除程序中的警告信息,常用屬性如下:
- unused 變量未使用
- deprecation 使用了不贊成使用的類或方法時的警告
- unchecked 執行了未檢查的轉換時的警告,例如當使用集合時沒有用泛型 (Generics) 來指定集合保存的類型。
- fallthrough 當 Switch 程序塊直接通往下一種情況而沒有 Break 時的警告。
- path 在類路徑、源文件路徑等中有不存在的路徑時的警告。?
- serial 當在可序列化的類上缺少 serialVersionUID 定義時的警告。?
- finally 任何 finally 子句不能正常完成時的警告。
- all 關於以上所有情況的警告。
定義註解
1.定義註解
@interface 名稱
: 就定義了一個註解,要想使用 在類,方法,屬性上直接@名稱
.
問題:
@interface 名稱
,是聲明瞭一個註解,它的本質是什麼?@Myannotation
的本質
import java.lang.annotation.Annotation;
interface MyAnnotation extends Annotation
{
}
- 註解的本質就是一個接口,它繼承了Annotation接口。
- 所的的註解都實現了這個接口,但是,不能手動實現。
- 註解是jdk1.5的新特性.
註解中的成員
接口中的成員:
- 屬性 : public static final
- 方法 : public abstract
註解成員
- 1.可以有屬性
- 註解中可以有屬性,但是基本不使用。
- 2.可以有方法
- 在開發中,一般使用註解時,只研究它的方法,我們一般管它叫做註解中的屬性.
- 1.可以有屬性
1.關於註解中的屬性(方法)的類型問題(返回值)
它的類型只能是以下幾種:
- 1.基本類型
- 整型:byte short int long
- 浮點:float double
- 字符:char
- 邏輯:boolean
- 2.String
- 3.Class
- 4.enum
- 5.Annotation
- 6.以上類型的一維數組。
- 1.基本類型
2.關於註解中有屬性,使用的問題
- 如果一個註解中有屬性,並且屬性沒有默認值,那麼我們在使用註解時,必須給註解的屬性賦值.
關於屬性賦值方式:
- 1.默認值問題
String st() default "abc";
- 2.如果是單值 :
註解 (屬性名稱=值)
- 例如:
@MyAnnotation3(i=1)
- 例如:
- 3.如果是數組
- 1.如果只賦一個值 註解(屬性名稱=值)
- 例如:
@MyAnnotation3(i=1)
- 例如:
- 2.如果要賦多個值 註解(屬性名稱={值1,值2,…})
- 例如:
@MyAnnotation3(i={1,2,3})
- 例如:
- 1.如果只賦一個值 註解(屬性名稱=值)
- 4.關於屬性名稱value問題
- 可以省略屬性名稱
- 例如
@MyAnnotation3("hello");
- 如果value屬性是一個數組:
@MyAnnotation3({"a","b"})
- 如果註解中有value屬性,還有其它屬性: 那麼value屬性名稱不能在省略.
- 1.默認值問題
元註解 — 修飾註解的註解
1.
@Retention
- 作用:是指定註解給誰使用.
它的屬性值只能是以下三個
- RetentionPolicy.SOURCE : 給編譯器使用 使用後拋棄
- RetentionPolicy.CLASS : 給解析器使用。當jvm加載完成後,就拋棄.
- RetentionPolicy.RUNTIME : 給程序員使用,jvm加載完成後,還存在。開發人員可以通過反射來獲取註解相關信息.
2.
@Target
- 作用:就是定義註解在什麼位置使用
- 指定註解修飾目標對象類型 TYPE 類、接口 FIELD 成員變量 METHOD 方法
3.
@Documented
- 作用:是通過javadoc生成的文檔中是否抽取註解描述.
4.
@Inherited
- 作用:是描述當前註解是否具有繼承性
想要開發,有功能的註解,對於程序員,一定會使用的元註解是:
- @Retention
- @Target
註解案例—銀行最大轉賬金額
目的:
- 1.怎樣通過反射來操作註解
- 2.註解可以替換配置文件。
代碼實現:
- 1.將銀行最大轉賬金額,定義在配置文件中,使用時,直接從配置文件中讀取.
- 2.使用註解來替換配置文件。
流程如下:
1.定義一個註解(BankInfo.java)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface BankInfo {
int maxMoney();
}
2.通過反射來獲取註解信息
- 1.獲取當前方法的Method對象。
- 1.得到Class對象
- 1.類名.class
- 2.對象.getClass()
- 3.Class.forName(String className);
- 2.得到Method對象
- Class.getDeclaredMethod(String methodName,Class…paramClass);
- 1.得到Class對象
- 2.在Method類中有一個 getAnnotation(Class annotationClass),可以獲取一個註解對象.
- 3.通過註解對象來調用其屬性.
- 1.獲取當前方法的Method對象。
eg:
// name1向name2轉賬money元--使用註解
@BankInfo(maxMoney = 100000)
public void account(String name1, String name2, int money)
throws NoSuchMethodException, SecurityException {
// 1.獲取當前方法的Method對象。
// 1.1 獲取當前類的Class對象
Class clazz = this.getClass();
// 1.2 獲取當前方法的Method對象.
Method method = clazz.getDeclaredMethod("account", String.class,
String.class, int.class);
boolean flag = method.isAnnotationPresent(BankInfo.class); // 判斷當前方法上是否有BankInfo這個註解.
if (flag) {
// 2.在Method類中有一個 getAnnotation(Class annotationClass),可以獲取一個註解對象.
BankInfo bif = method.getAnnotation(BankInfo.class);
// 3.通過註解對象來調用其屬性.
int maxMoney = bif.maxMoney();
if (money > maxMoney) {
throw new RuntimeException("最大轉賬金額爲:" + maxMoney + "元");
}
System.out.println(name1 + "向" + name2 + "轉賬:" + money + "元");
}
}
- 註解可以替換配置文件,替換的是什麼?
- 配置文件的出現,它的主要目的就是解耦合。但是隨着現在開發程序越來越龐大,配置文件的缺點就出現了,配置文件內容越來越龐大,就不利於我們開發與閱讀.這時就出現了註解,因爲註解可以直接寫在代碼上,並且,通過註解也可以解耦合。
註解示例2–jdbc連接
- 數據庫建立:
create table products(
id int primary key auto_increment,
name varchar(40),
price double
);
insert into products values(null,'冰箱',3000);
insert into products values(null,'洗衣機',2000);
insert into products values(null,'電視',5000);
- JdbcInfo.java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface JdbcInfo {
String driverClassName();
String url();
String username();
String password();
}
- JdbcUtils.java
@JdbcInfo(driverClassName = "com.mysql.jdbc.Driver", url = "jdbc:mysql:///day24", username = "root", password = "abc")
public static Connection getConnectionByAnnotation(String[] args) throws Exception {
System.out.println(Arrays.toString(args));
// 得到當前方法上的註解JdbcInfo
Method method = JdbcUtils.class
.getDeclaredMethod("getConnectionByAnnotation",String[].class);
JdbcInfo jif = method.getAnnotation(JdbcInfo.class);
String driverClassName = jif.driverClassName();
String url = jif.url();
String username = jif.username();
String password = jif.password();
// 1.加載驅動
Class.forName(driverClassName);
// 2.獲取連接
Connection con = DriverManager.getConnection(url, username, password);
return con;
}