jsp界面自动生成文件注释_实施注释界面
jsp界面自動生成文件注釋
對于Java開發人員而言,每天都需要使用注釋。 如果沒有其他簡單的@Override注釋,那該響了。 創建注釋要復雜一些。 在運行時通過反射使用“自制”注釋或在編譯時調用注釋處理器也是一種復雜性。 但是我們很少“實現”注釋接口。 暗中有人在幕后一定為我們做。
當我們有注釋時:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface AnnoWithDefMethod {String value() default "default value string"; }然后用這個注解注解的類
@AnnoWithDefMethod("my default value") public class AnnotatedClass { }最后我們在運行時執行期間獲取注釋時
AnnoWithDefMethod awdm = AnnotatedClass.class.getAnnotation(AnnoWithDefMethod.class);那么我們如何進入變量awdm呢? 它是一個對象。 對象是類的實例,而不是接口。 這意味著Java運行時的幕后人員已經“實現”了注釋接口。 我們甚至可以打印出對象的特征:
System.out.println(awdm.value());System.out.println(Integer.toHexString(System.identityHashCode(awdm)));System.out.println(awdm.getClass());System.out.println(awdm.annotationType());for (Method m : awdm.getClass().getDeclaredMethods()) {System.out.println(m.getName());}得到類似的結果
my default value 60e53b93 class com.sun.proxy.$Proxy1 interface AnnoWithDefMethod value equals toString hashCode annotationType因此,我們不需要實現注釋接口,但是如果需要的話,可以實現。 但是我們為什么要那樣? 到目前為止,我遇到了一種解決方案:配置guice依賴項注入。
Guice是Google的DI容器。 綁定的配置以說明性方式作為Java代碼提供,如文檔頁面中所述 。 您可以將類型綁定到實現,只需聲明
bind(TransactionLog.class).to(DatabaseTransactionLog.class);這樣,所有注入的TransactionLog實例將屬于DatabaseTransactionLog 。 如果要在代碼的不同字段中注入不同的注入,則應以某種方式向Guice發出信號,例如創建注釋,將注釋放在字段或構造函數參數上并聲明
bind(CreditCardProcessor.class).annotatedWith(PayPal.class).to(PayPalCreditCardProcessor.class);這要求PayPal作為注釋接口,并且您需要編寫一個新的注釋接口,以與每個CreditCardProcessor實現或更多實現相伴,以便您可以在綁定配置中用信號通知和分離實現類型。 僅有太多的注釋類,這可能是一個過大的殺傷力。
除此之外,您還可以使用名稱。 您可以使用注解@Named("CheckoutPorcessing")注釋注入目標并配置綁定
bind(CreditCardProcessor.class).annotatedWith(Names.named("CheckoutProcessing")).to(CheckoutCreditCardProcessor.class);這是眾所周知的技術,已廣泛用于DI容器中。 您指定類型(接口),創建實現,最后使用名稱定義綁定類型。 這樣做沒有問題,只不過在您鍵入處理而不是處理時很難注意到。 在綁定(運行時)失敗之前,此類錯誤將一直隱藏。 您不能簡單地使用final static String來保存實際值,因為它不能用作注釋參數。 您可以在綁定定義中使用這樣的常量字段,但是它仍然是重復的。
這個想法是使用其他東西代替String。 編譯器檢查的內容。 顯而易見的選擇是使用一個類。 要實現該代碼,可以從NamedImpl的代碼中學習,該代碼是實現注釋接口的類。 代碼是這樣的(注意: Klass是這里未列出的注釋接口。):
class KlassImpl implements Klass {Class<? extends Annotation> annotationType() {return Klass.class}static Klass klass(Class value){return new KlassImpl(value: value)}public boolean equals(Object o) {if(!(o instanceof Klass)) {return false;}Klass other = (Klass)o;return this.value.equals(other.value());}public int hashCode() {return 127 * "value".hashCode() ^ value.hashCode();}Class value@OverrideClass value() {return value} }實際的綁定看起來像
@Injectpublic RealBillingService(@Klass(CheckoutProcessing.class) CreditCardProcessor processor,TransactionLog transactionLog) {...}bind(CreditCardProcessor.class).annotatedWith(Klass.klass(CheckoutProcessing.class)).to(CheckoutCreditCardProcessor.class);在這種情況下,編譯器很可能會發現任何錯字。 幕后實際上發生了什么,為什么我們要求實現注釋接口?
配置綁定后,我們提供一個對象。 調用Klass.klass(CheckoutProcessing.class)將創建一個實例KlassImpl當吉斯試圖決定是否實際綁定配置有效結合CheckoutCreditCardProcessor到CreditCardProcessor論點的構造RealBillingService它只是調用該方法equals()上注釋對象。 如果Java運行時創建的實例(請記住Java運行時創建的實例的名稱類似于class com.sun.proxy.$Proxy1 ),并且我們提供的實例相等,那么將使用綁定配置,否則必須進行其他綁定比賽。
還有另一個問題。 實現equals()是不夠的。 您可能(并且,如果您是Java程序員(這就是為什么您還要讀這篇文章(您當然不是Lisp程序員)),那么您也應該)記住,如果重寫equals()還必須重寫hashCode() 。 實際上,您應該提供一個與Java運行時創建的類進行相同計算的實現。 這樣做的原因是,該比較可能不會直接由應用程序執行。 Guice可能(確實)正在從Map查找注釋對象。 在那種情況下,哈希碼用于標識比較對象必須所在的存儲桶,之后使用equals()方法檢查身份。 如果在創建Java運行時的情況下hashCode()方法返回的數字不同,則out對象將無法匹配。 equals()將返回true,但不會為它們調用它,因為在映射中找不到該對象。
方法hashCode的實際算法在接口java.lang.annotation的文檔中描述。 我以前看過此文檔,但了解我第一次使用Guice并實現類似的注釋接口實現類時定義算法的原因。
最后一件事是該類還必須實現annotationType() 。 為什么? 如果我知道了,我會寫。
翻譯自: https://www.javacodegeeks.com/2016/03/implementing-annotation-interface.html
jsp界面自動生成文件注釋
總結
以上是生活随笔為你收集整理的jsp界面自动生成文件注释_实施注释界面的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 润唇膏哪个牌子好用又健康(精选6款润唇膏
- 下一篇: 接口中默认方法和静态方法_接口中的默认方