這是我參與更文挑戰的第28天,活動詳情查看: 更文挑戰java
spring開源框架,裏面全是經過註解實現的spring
spring開源框架,裏面全是經過註解實現的,咱們使用在使用的時候也嚐到很多好處,因此就抽空看看Java給咱們提供的註解機制的使用。編程
Overridemarkdown
SuppressWarningsapp
- deprecation,使用了過期的類或方法時的警告
- unchecked,執行了未檢查的轉換時的警告
- fallthrough,當 switch 程序塊直接通往下一種狀況而沒有 break 時的警告
- path,在類路徑、源文件路徑等中有不存在的路徑時的警告
- serial,當在可序列化的類上缺乏serialVersionUID 定義時的警告
- finally ,任何 finally 子句不能正常完成時的警告
- all,關於以上全部狀況的警告
複製代碼
Deprecated框架
它的做用是對不該該再使用的方法添加註解,當編程人員使用這些方法時,將會在編譯時顯示提示信息,它與javadoc裏的@deprecated標記有相同的功能,準確的說,它還不如javadoc @deprecated,由於它不支持參數,使用@Deprecated的示例代碼示例以下: ide
ElementTypesvn
RetentionPolicy函數
Documented工具
/**
* Indicates that annotations with a type are to be documented by javadoc
* and similar tools by default. This type should be used to annotate the
* declarations of types whose annotations affect the use of annotated
* elements by their clients. If a type declaration is annotated with
* Documented, its annotations become part of the public API
* of the annotated elements.
*
* @author Joshua Bloch
* @since 1.5
*/
複製代碼
Target
/**
* Indicates the kinds of program element to which an annotation type
* is applicable. If a Target meta-annotation is not present on an
* annotation type declaration, the declared type may be used on any
* program element. If such a meta-annotation is present, the compiler
* will enforce the specified usage restriction.
*
* For example, this meta-annotation indicates that the declared type is
* itself a meta-annotation type. It can only be used on annotation type
* declarations:
* <pre>
* @Target(ElementType.ANNOTATION_TYPE)
* public @interface MetaAnnotationType {
* ...
* }
* </pre>
* This meta-annotation indicates that the declared type is intended solely
* for use as a member type in complex annotation type declarations. It
* cannot be used to annotate anything directly:
* <pre>
* @Target({})
* public @interface MemberType {
* ...
* }
* </pre>
* It is a compile-time error for a single ElementType constant to
* appear more than once in a Target annotation. For example, the
* following meta-annotation is illegal:
* <pre>
* @Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})
* public @interface Bogus {
* ...
* }
* </pre>
*/
複製代碼
一樣上面仍然是Java JDK官網的說明,首先是說若是target指定的類型元素不存在的話,那麼經過target指定的註解將能夠用在任何地方,若是target指定元素,則該註解必須只能用在指定的元素上,target指定的元素是經過ElementType這個枚舉類指定的,裏面的枚舉就是target能夠指定的值。官網上的列子是Target(ElementType.ANNOTATION_TYPE)代表這個註解只能用在註解本省上面。還有一種屬性不在ElementType枚舉中,就是target({})
,就是經過{}的註解是用來在負責註解上的成員變量,他不能用在其餘的地方。
ElementType.CONSTRUCTOR:用於描述構造器
ElementType.FIELD:成員變量、對象、屬性(包括enum實例)
ElementType.LOCAL_VARIABLE:用於描述局部變量
ElementType.METHOD:用於描述方法
ElementType.PACKAGE:用於描述包
ElementType.PARAMETER:用於描述參數
ElementType.TYPE:用於描述類、接口(包括註解類型) 或enum聲明
Retention
/**
* Indicates how long annotations with the annotated type are to
* be retained. If no Retention annotation is present on
* an annotation type declaration, the retention policy defaults to
* {@code RetentionPolicy.CLASS}.
*
* <p>A Retention meta-annotation has effect only if the
* meta-annotated type is used directly for annotation. It has no
* effect if the meta-annotated type is used as a member type in
* another annotation type.
*
* @author Joshua Bloch
* @since 1.5
*/
複製代碼
這個類的屬性是經過RetentionPolicy這個枚舉類列舉屬性的,這個主要的做用是指定咱們的註解存在的時間或者說是存在的時刻。這個屬性只有直接用在原註釋類型的註解上纔有效。若是用在其餘註解的成員變量上就沒有效果了。
RetentionPolicy.SOURCE : 在編譯階段丟棄。這些註解在編譯結束以後就再也不有任何意義,因此它們不會寫入字節碼。@Override, @SuppressWarnings都屬於這類註解。
RetentionPolicy.CLASS : 在類加載的時候丟棄。在字節碼文件的處理中有用。註解默認使用這種方式
- RetentionPolicy.RUNTIME : 始終不會丟棄,運行期也保留該註解,所以可使用反射機制讀取該註解的信息。咱們自定義的註解一般使用這種方式。
複製代碼
Inherited
/**
* Indicates that an annotation type is automatically inherited. If
* an Inherited meta-annotation is present on an annotation type
* declaration, and the user queries the annotation type on a class
* declaration, and the class declaration has no annotation for this type,
* then the class's superclass will automatically be queried for the
* annotation type. This process will be repeated until an annotation for this
* type is found, or the top of the class hierarchy (Object)
* is reached. If no superclass has an annotation for this type, then
* the query will indicate that the class in question has no such annotation.
*
* <p>Note that this meta-annotation type has no effect if the annotated
* type is used to annotate anything other than a class. Note also
* that this meta-annotation only causes annotations to be inherited
* from superclasses; annotations on implemented interfaces have no
* effect.
*
* @author Joshua Bloch
* @since 1.5
*/
複製代碼
/**
* 該註解用於doc文檔
* 該註解用於類的構造函數的註解
* 該註解盡在運行期間有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
public @interface ConstructorAnno
{
String decs() default "我是描述構造函數的註解";
}
複製代碼
/**
* 該註解用於生成doc文檔
* 該註解用於在類的字段屬性上的註解
* 該註解盡在運行期間有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldAnno
{
String desc() default "我是描述字段的註解";
}
複製代碼
/**
* 該註解用於生成doc文檔
* 該註解用於在局部變量上的註解
* 該註解盡在運行期間有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.LOCAL_VARIABLE)
@Retention(RetentionPolicy.RUNTIME)
public @interface LocalAnno
{
String desc() default "我是描述一個局部變量的註解";
}
複製代碼
/**
* 這個註解用於生成doc文檔
* 這個註解用於類的方法上的註解
* 這個註解盡在運行期間有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodAnno
{
//默認提交時間 2017-2-28
String time() default "2017-2-28";
//默認 男 true 男 false 女
boolean sex() default true;
}
複製代碼
/**
* 該註解用於生成doc文檔
* 該註解用於在包的註解
* 該註解盡在運行期間有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.PACKAGE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PackageAnno
{
String desc() default "我是描述包的註解";
}
複製代碼
/**
* 該註解用於doc文檔的生成
* 該註解用於類的參數中
* 該註解盡在運行期間有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface StuInfo
{
String value() default "";
}
複製代碼
/**
* 該註解用於生活曾doc文檔
* 該註解用於在類的註解
* 該註解盡在運行期間有效
* @author xinhua
*
*/
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TypeAnno
{
String desc() default "我是描述類型的註解";
}
複製代碼
/**
* 測試全部類型的註解的做用
* @author xinhua
*
*/
public @TypeAnno(desc="我是普通類")class User
{
@FieldAnno
private String UID;
@FieldAnno(desc="我是UserName的")
private String userName;
@ConstructorAnno
public User(){
}
@MethodAnno(time="2015-12-8" , sex=false)
public void doHomeWork(@StuInfo(value="211311084") String UID, @StuInfo(value="張新華")String UserName){
@LocalAnno(desc="flag的局部變量")boolean flag;
}
}
複製代碼
public interface UserImp
{
public void DoHouseWork(@StuInfo(value="我是小學生")String stuType,@StuInfo(value="我在大掃除")String things);
}
複製代碼
/**
* 開始經過反射獲取註解內容
* @author xinhua
*
*/
public class Junit
{
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException
{
Class<?> userClass = Class.forName("tom.change.annotation.User");
//實例化
Object userObject = userClass.newInstance();
//1--獲取最外層的就是類的註解 TypeAnno
System.out.println(".......................類註解.......................");
TypeAnno typeAnno= userClass.getAnnotation(TypeAnno.class);
System.out.println(typeAnno.desc());
//2--獲取字段註解 首先獲取經過反射獲取類中的屬性字段
System.out.println(".......................字段註解.......................");
Field[] fields = userClass.getDeclaredFields();
for (Field field : fields)
{
FieldAnno fieldAnno = field.getAnnotation(FieldAnno.class);
System.out.println(fieldAnno.desc());
}
//3-- 方法的註解
System.out.println(".......................方法註解.......................");
Method method = userClass.getMethod("doHomeWork", String.class,String.class);
MethodAnno methodAnno = method.getAnnotation(MethodAnno.class);
System.out.println(methodAnno.time()+"@@@"+methodAnno.sex());
//4-- 參數的註解 動態代理方式實現參數
System.out.println(".......................參數註解.......................");
UserImp userImp=getMethodParameter(UserImp.class);
userImp.DoHouseWork("張新華", "--》掃地");
//5--局部變量註解
System.out.println(".......................局部變量註解.......................");
//贊未得到到
}
public static<T> T getMethodParameter(Class<T> target){
return (T)Proxy.newProxyInstance(target.getClassLoader(), new Class<?>[]{target}, new InvocationHandler()
{
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (int i=0;i<parameterAnnotations.length;i++)
{
Annotation[] annotations=parameterAnnotations[i];
StuInfo stuInfo =(StuInfo) annotations[0];
System.out.println(stuInfo.value()+"@@@"+args[i]);
}
return null;
}
});
}
}
複製代碼