<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ### 默認值限制 編譯器對于元素的默認值有些過于挑剔。首先,元素不能有不確定的值。也就是說,元素要么有默認值,要么就在使用注解時提供元素的值。 這里有另外一個限制:任何非基本類型的元素, 無論是在源代碼聲明時還是在注解接口中定義默認值時,都不能使用 null 作為其值。這個限制使得處理器很難表現一個元素的存在或者缺失的狀態,因為在每個注解的聲明中,所有的元素都存在,并且具有相應的值。為了繞開這個約束,可以自定義一些特殊的值,比如空字符串或者負數用于表達某個元素不存在。 ```java // annotations/SimulatingNull.java import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface SimulatingNull { int id() default -1; String description() default ""; } ``` 這是一個在定義注解的習慣用法。 ### 生成外部文件 當有些框架需要一些額外的信息才能與你的源代碼協同工作,這種情況下注解就會變得十分有用。像 Enterprise JavaBeans (EJB3 之前)這樣的技術,每一個 Bean 都需要需要大量的接口和部署描述文件,而這些就是“樣板”文件。Web Service,自定義標簽庫以及對象/關系映射工具(例如 Toplink 和 Hibernate)通常都需要 XML 描述文件,而這些文件脫離于代碼之外。除了定義 Java 類,程序員還必須忍受沉悶,重復的提供某些信息,例如類名和包名等已經在原始類中已經提供的信息。每當你使用外部描述文件時,他就擁有了一個類的兩個獨立信息源,這經常導致代碼的同步問題。同時這也要求了為項目工作的程序員在知道如何編寫 Java 程序的同時,也必須知道如何編輯描述文件。 假設你想提供一些基本的對象/關系映射功能,能夠自動生成數據庫表。你可以使用 XML 描述文件來指明類的名字、每個成員以及數據庫映射的相關信息。但是,通過使用注解,你可以把所有信息都保存在 **JavaBean** 源文件中。為此你需要一些用于定義數據庫表名稱、數據庫列以及將 SQL 類型映射到屬性的注解。 以下是一個注解的定義,它告訴注解處理器應該創建一個數據庫表: ```java // annotations/database/DBTable.java package annotations.database; import java.lang.annotation.*; @Target(ElementType.TYPE) // Applies to classes only @Retention(RetentionPolicy.RUNTIME) public @interface DBTable { String name() default ""; } ``` 在 `@Target` 注解中指定的每一個 **ElementType** 就是一個約束,它告訴編譯器,這個自定義的注解只能用于指定的類型。你可以指定 **enum ElementType** 中的一個值,或者以逗號分割的形式指定多個值。如果想要將注解應用于所有的 **ElementType**,那么可以省去 `@Target` 注解,但是這并不常見。 注意 **@DBTable** 中有一個 `name()` 元素,該注解通過這個元素為處理器創建數據庫時提供表的名字。 如下是修飾字段的注解: ```java // annotations/database/Constraints.java package annotations.database; import java.lang.annotation.*; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Constraints { boolean primaryKey() default false; boolean allowNull() default true; boolean unique() default false; } ``` ```java // annotations/database/SQLString.java package annotations.database; import java.lang.annotation.*; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface SQLString { int value() default 0; String name() default ""; Constraints constraints() default @Constraints; } ``` ```java // annotations/database/SQLInteger.java package annotations.database; import java.lang.annotation.*; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface SQLInteger { String name() default ""; Constraints constraints() default @Constraints; } ``` **@Constraints** 注解允許處理器提供數據庫表的元數據。**@Constraints** 代表了數據庫通常提供的約束的一小部分,但是它所要表達的思想已經很清楚了。`primaryKey()`,`allowNull()` 和 `unique()` 元素明顯的提供了默認值,從而使得在大多數情況下,該注解的使用者不需要輸入太多東西。 另外兩個 **@interface** 定義的是 SQL 類型。如果希望這個框架更有價值的話,我們應該為每個 SQL 類型都定義相應的注解。不過作為示例,兩個元素足夠了。 這些 SQL 類型具有 `name()` 元素和 `constraints()` 元素。后者利用了嵌套注解的功能,將數據庫列的類型約束信息嵌入其中。注意 `constraints()` 元素的默認值是 **@Constraints**。由于在 **@Constraints** 注解類型之后,沒有在括號中指明 **@Constraints** 元素的值,因此,**constraints()** 的默認值為所有元素都為默認值的 **@Constraints** 注解。如果要使得嵌入的 **@Constraints** 注解中的 `unique()` 元素為 true,并作為 `constraints()` 元素的默認值,你可以像如下定義: ```java // annotations/database/Uniqueness.java // Sample of nested annotations package annotations.database; public @interface Uniqueness { Constraints constraints() default @Constraints(unique = true); } ``` 下面是一個簡單的,使用了如上注解的類: ```java // annotations/database/Member.java package annotations.database; @DBTable(name = "MEMBER") public class Member { @SQLString(30) String firstName; @SQLString(50) String lastName; @SQLInteger Integer age; @SQLString(value = 30, constraints = @Constraints(primaryKey = true)) String reference; static int memberCount; public String getReference() { return reference; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } @Override public String toString() { return reference; } public Integer getAge() { return age; } } ``` 類注解 **@DBTable** 注解給定了元素值 MEMBER,它將會作為標的名字。類的屬性 **firstName** 和 **lastName** 都被注解為 **@SQLString** 類型并且給了默認元素值分別為 30 和 50。這些注解都有兩個有趣的地方:首先,他們都使用了嵌入的 **@Constraints** 注解的默認值;其次,它們都是用了快捷方式特性。如果你在注解中定義了名為 **value** 的元素,并且在使用該注解時,**value** 為唯一一個需要賦值的元素,你就不需要使用名—值對的語法,你只需要在括號中給出 **value** 元素的值即可。這可以應用于任何合法類型的元素。這也限制了你必須將元素命名為 **value**,不過在上面的例子中,這樣的注解語句也更易于理解: ```java @SQLString(30) ``` 處理器將在創建表的時候使用該值設置 SQL 列的大小。 默認值的語法雖然很靈巧,但是它很快就變的復雜起來。以 **reference** 字段的注解為例,上面擁有 **@SQLString** 注解,但是這個字段也將成為表的主鍵,因此在嵌入的 **@Constraint** 注解中設定 **primaryKey** 元素的值。這時事情就變的復雜了。你不得不為這個嵌入的注解使用很長的鍵—值對的形式,來指定元素名稱和 **@interface** 的名稱。同時,由于有特殊命名的 **value** 也不是唯一需要賦值的元素,因此不能再使用快捷方式特性。如你所見,最終結果不算清晰易懂。
                  <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>

                              哎呀哎呀视频在线观看