<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] # 什么是注解 注解就是符合一定格式的語法 @xxxx 注解作用: 注釋:在閱讀程序時清楚----給程序員看的 注解:給jvm看的,給機器看的 注解在目前而言最主流的應用:代替配置文件 關于配置文件與注解開發的優缺點: 注解優點:開發效率高 成本低 注解缺點:耦合性大 并且不利于后期維護 # 注解的應用結構圖 注解就相當于一個你的源程序中要調用的一個類,要在源程序中應用某個注解,得先準備好了這個注解類,就像你要調用某個類,得先要開發好這個類 ![](https://box.kancloud.cn/daa3919053b55de2763885e274800e50_614x247.png) # jdk5提供的注解 ~~~ @Override:告知編譯器此方法是覆蓋父類的 @Deprecated:標注過時 @SuppressWarnings:壓制警告 deprecation, 忽略過時 rawtypes 忽略類型安全 unused 忽略不使用 unchecked 忽略安全檢查 null 忽略空指針 all 忽略所有 ~~~ # 自定義注解 ## 編寫一個注解 關鍵字:@interface 注解的屬性: 語法:返回值 名稱(); 注意:如果屬性的名字是value,并且注解的屬性值有一個 那么在使用注解時可以省略value ~~~ public @interface MyAnno{ String value(); int age() default 28; } ~~~ 注解屬性類型只能是以下幾種 1. 基本類型 2. String 3. 枚舉類型 4. 注解類型 5. Class類型 6. 以上類型的一維數組類型 ## 使用注解 在類/方法/字段 上面是@XXX ~~~ @MyAnno("zhansan") public class TestAnno { } ~~~ ## 解析使用了注解的類 介入一個概念:元注解:代表修飾注解的注解,作用:限制定義的注解的特性 ### `@Retention` ~~~ SOURCE: 注解在源碼級別可見 CLASS:注解在字節碼文件級別可見 RUNTIME:注解在整個運行階段都可見 ~~~ 如果`@Retention`不存在,則該`Annotation`默認為`CLASS` ![](https://box.kancloud.cn/16e2af0406570f1dd7f2b295184e7c9c_838x334.png) ### `@Target` ~~~ 代表注解修飾的范圍:類上使用,方法上使用,字段上使用 FIELD:字段上可用此注解 METHOD:方法上可以用此注解 TYPE:類/接口上可以使用此注解 CONSTRUCTOR: 構造方法上使用 PARAMETER: 方法參數上使用 ~~~ ### `@Repeatable` 使用`@Repeatable`這個元注解可以定義`Annotation`是否可重復。這個注解應用不是特別廣泛。 ~~~ @Repeatable @Target(ElementType.TYPE) public @interface Report { int type() default 0; String level() default "info"; String value() default ""; } ~~~ 經過`@Repeatable`修飾后,在某個類型聲明處,就可以添加多個`@Report`注解: ~~~ @Report(type=1, level="debug") @Report(type=2, level="warning") public class Hello { } ~~~ ### `@Inherited` 使用`@Inherited`定義子類是否可繼承父類定義的`Annotation`。`@Inherited`僅針對`@Target(ElementType.TYPE)`類型的`annotation`有效,并且僅針對`class`的繼承,對`interface`的繼承無效: ~~~ @Inherited @Target(ElementType.TYPE) public @interface Report { int type() default 0; String level() default "info"; String value() default ""; } ~~~ 在使用的時候,如果一個類用到了`@Report`: ~~~ @Report(type=1) public class Person { } ~~~ 則它的子類默認也定義了該注解: ~~~ public class Student extends Person { } ~~~ ### 例子 ~~~ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnno { //注解的屬性 String name(); int age() default 28; } ~~~ 注意:要想解析使用了注解的類 , 那么該注解的Retention必須設置成Runtime 關于注解解析的實質:從注解中解析出屬性值 字節碼對象存在于獲得注解相關的方法 ~~~ isAnnotationPresent(Class<? extends Annotation> annotationClass) : 判斷該字節碼對象身上是否使用該注解了 getAnnotation(Class<A> annotationClass) :獲得該字節碼對象身上的注解對象 ~~~ ~~~ @MyAnno(name = "zhangsan") public class MyAnnoTest { @SuppressWarnings("all") @MyAnno(name = "zhangsan") //@MyAnno({ "aaa","bbb","ccc"}) public void show(String str){ System.out.println("show running..."); } } ~~~ ~~~ //解析show方法上面的@MyAnno //直接的目的是 獲得show方法上的@MyAnno中的參數 //獲得show方法的字節碼對象 Class clazz = MyAnnoTest.class; Method method = clazz.getMethod("show", String.class); //獲得show方法上的@MyAnno MyAnno annotation = method.getAnnotation(MyAnno.class); //獲得@MyAnno上的屬性值 System.out.println(annotation.name());//zhangsan System.out.println(annotation.age());//28 //根據業務需求寫邏輯代碼 ~~~ # `@NonNull和@Nullable` 用 `@Nullable` 和 `@NotNull` 注解來顯示表明可為空的參數和以及返回值。 這樣就夠在編譯的時候處 理空值而不是在運行時拋出 NullPointerExceptions。 # 處理注解 因為注解定義后也是一種`class`,所有的注解都繼承自`java.lang.annotation.Annotation`,因此,讀取注解,需要使用反射API。 Java提供的使用反射API讀取`Annotation`的方法包括: 判斷某個注解是否存在于`Class`、`Field`、`Method`或`Constructor`: * `Class.isAnnotationPresent(Class)` * `Field.isAnnotationPresent(Class)` * `Method.isAnnotationPresent(Class)` * `Constructor.isAnnotationPresent(Class)` 例如: ~~~ // 判斷@Report是否存在于Person類: Person.class.isAnnotationPresent(Report.class); ~~~ 使用反射API讀取Annotation: * `Class.getAnnotation(Class)` * `Field.getAnnotation(Class)` * `Method.getAnnotation(Class)` * `Constructor.getAnnotation(Class)` 例如: ~~~ // 獲取Person定義的@Report注解: Report report = Person.class.getAnnotation(Report.class); int type = report.type(); String level = report.level(); ~~~ 使用反射API讀取`Annotation`有兩種方法。方法一是先判斷`Annotation`是否存在,如果存在,就直接讀取: ~~~ Class cls = Person.class; if (cls.isAnnotationPresent(Report.class)) { Report report = cls.getAnnotation(Report.class); ... } ~~~ 第二種方法是直接讀取`Annotation`,如果`Annotation`不存在,將返回`null`: ~~~ Class cls = Person.class; Report report = cls.getAnnotation(Report.class); if (report != null) { ... } ~~~ 讀取方法、字段和構造方法的`Annotation`和Class類似。但要讀取方法參數的`Annotation`就比較麻煩一點,因為方法參數本身可以看成一個數組,而每個參數又可以定義多個注解,所以,一次獲取方法參數的所有注解就必須用一個二維數組來表示。例如,對于以下方法定義的注解: ~~~ public void hello(@NotNull @Range(max=5) String name, @NotNull String prefix) { } ~~~ 要讀取方法參數的注解,我們先用反射獲取`Method`實例,然后讀取方法參數的所有注解: ~~~ // 獲取Method實例: Method m = ... // 獲取所有參數的Annotation: Annotation[][] annos = m.getParameterAnnotations(); // 第一個參數(索引為0)的所有Annotation: Annotation[] annosOfName = annos[0]; for (Annotation anno : annosOfName) { if (anno instanceof Range) { // @Range注解 Range r = (Range) anno; } if (anno instanceof NotNull) { // @NotNull注解 NotNull n = (NotNull) anno; } } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看