java注解用來(lái)描述java代碼中的元信息,通常情況下,注解不會(huì)影響代碼執(zhí)行,盡管有些情況下,注解可以做到影響代碼的執(zhí)行。
java注解在java5被添加進(jìn)來(lái),
java注解的作用
java注解通常被用來(lái)用作以下目的
- 編譯器指令
- 構(gòu)建時(shí)指令
- 運(yùn)行時(shí)指令
java內(nèi)置了三種編譯器指令,本文后面會(huì)詳細(xì)介紹。
java注解可以應(yīng)用于構(gòu)建時(shí),即當(dāng)你構(gòu)建你的項(xiàng)目時(shí)。構(gòu)建的過(guò)程包括產(chǎn)生源代碼、編譯源代碼、產(chǎn)生xml文件,將編譯過(guò)的代碼或文件打包進(jìn)jar文件等等。軟件的構(gòu)建通常使用Apache Ant或者Apache Maven這樣的工具自動(dòng)完成。構(gòu)建工具會(huì)掃描java代碼里的注解,然后根據(jù)這些注解產(chǎn)生源代碼或者其它的文件。
通常情況下,注解不會(huì)出現(xiàn)在編譯之后的java代碼中,但是想要出現(xiàn)也是可以的。java支持運(yùn)行時(shí)注解。這些注解可以通過(guò)java反射訪問,運(yùn)行時(shí)注解主要是提供給程序或者第三方API一些指令。
注解基礎(chǔ)
一個(gè)簡(jiǎn)單的java注解類似于下面這種
@Entity
@符號(hào)告訴編譯器這是一個(gè)注解,跟在@符號(hào)后面的是注解的名字。上述例子中注解的名字是Entity。
注解元素
java注解可以使用元素設(shè)置一些值。元素類似于屬性或者參數(shù)。下面是一個(gè)包含元素注解的例子。
@Entity(tableName = "vehicles")
上述注解元素名稱是tableName,值是vehicles,沒有元素的注解不需要括號(hào)。注解可以包含多個(gè)元素,下面就是包含多個(gè)元素的例子。
@Entity(tableName = "vehicles", primaryKey = "id")
當(dāng)注解只包含一個(gè)元素時(shí),你可以省去寫元素的名字,直接賦值即可。下面的例子就是直接賦值。
@InsertNew("yes")
注解使用
注解可以在以下場(chǎng)合被使用到
類
接口
方法
方法參數(shù)
屬性
-
局部變量
下面是一個(gè)完整使用注解的例子。@Entity public class Vehicle { @Persistent protected String vehicleName = null; @Getter public String getVehicleName() { return this.vehicleName; } public void setVehicleName(@Optional vehicleName) { this.vehicleName = vehicleName; } public List addVehicleNameToList(List names) { @Optional List localNames = names; if(localNames == null) { localNames = new ArrayList(); } localNames.add(getVehicleName()); return localNames; } }
內(nèi)置的java注解
java有三種內(nèi)置的注解,用來(lái)為編譯器提供指令。
- @Deprecated
- @Override
- @SuppressWarnings
@Deprecated
- 可以用來(lái)標(biāo)記類、方法、屬性
- 如果上述三種元素不再使用可以用@Deprecated標(biāo)記
- 如果代碼使用了@Deprecated注解的類,方法,或者屬性,編譯器會(huì)給出警告。
@Deprecated注解使用很簡(jiǎn)單,以下是使用@Deprecated注解一個(gè)已經(jīng)棄用的類。
@Deprecated
public class MyComponent {
}
當(dāng)我們使用@Deprecated注解后,建議配合使用對(duì)應(yīng)的@deprecated JavaDoc符號(hào),并解釋說(shuō)明為什么這個(gè)類,方法或?qū)傩员粭売茫呀?jīng)替代方案是什么。例子如下:
@Deprecated
/**
@deprecated Use MyNewComponent instead.
*/
public class MyComponent {
}
@Override
@Override注解用來(lái)標(biāo)示重寫父類中的方法,如果這個(gè)方法沒有重寫父類的方法,而添加這個(gè)注解,編譯器會(huì)報(bào)錯(cuò)。實(shí)際上,在子類中重寫父類或者接口中的方法,@Override并不是必須的。但是,仍然建議你使用這個(gè)注解。假設(shè)你修改了父類的方法的名字,那么之前重寫的子類方法將不再屬于重寫,如果沒有@Overide,你將不會(huì)察覺到這個(gè)子類的方法。有了這個(gè)注解修飾,編譯器則會(huì)提示你這些信息。
使用@Override的例子如下。
public class MySuperClass {
public void doTheThing() {
System.out.println("Do the thing");
}
}
public class MySubClass extends MySuperClass{
@Override
public void doTheThing() {
System.out.println("Do it differently");
}
}
___
@SuppressWarnings
- @SuppressWarning用來(lái)抑制編譯生成警告信息
- 可以修飾的元素為類,方法,方法參數(shù),屬性,局部變量
當(dāng)一個(gè)方法調(diào)用了一個(gè)被棄用的方法或者是不安全的類型轉(zhuǎn)換,編譯器就會(huì)產(chǎn)生警告,你可以使用@SuppressWarnings抑制編譯器產(chǎn)生警告。
使用示例如下
@SuppressWarnings
public void methodWithWarning() {
}
創(chuàng)建自己的注解
可以定義自己的注解,和類或者接口一樣,注解可以定義在自己的文件中。
使用自定義注解如下
@interface MyAnnotation {
String value();
String name();
int age();
String[] newNames();
}
上述例子定義了一個(gè)叫MyAnnotation的注解,它有四個(gè)元素。@interface告訴編譯器這是一個(gè)注解。
每個(gè)元素的定義與接口中的方法定義類似,它有數(shù)據(jù)類型和名字。這些類型可以是
原始數(shù)據(jù)類型
String
Class
annotation
枚舉
-
一維數(shù)組
以下示例為應(yīng)用自定義注解
@MyAnnotation( value="123", name="Jakob", age=37, newNames={"Jenkov", "Peterson"} ) public class MyClass { }
注意我們需要為所有元素設(shè)置值一個(gè)都不能少
元素的默認(rèn)值
對(duì)于元素中的注解,我們可以為其設(shè)置默認(rèn)值,使用方法為
@interface MyAnnotation { String value() default ""; String name(); int age(); String[] newNames(); }
上述注解中我們?cè)O(shè)置value的值為空字符串,那么我們?cè)谑褂么俗⒔鈺r(shí),可以不設(shè)置value的值,即讓value使用設(shè)置的空字符串的默認(rèn)值。示例如下
@MyAnnotation( name="Jakob", age=37, newNames={"Jenkov", "Peterson"} ) public class MyClass { }
@Retention
@Retention用來(lái)修飾注解的注解,使用這個(gè)注解,我們可以做到