[英]Optional or default generic parameters
假設我有 3 個通用參數:
public static interface Mapper<V,T,E> {
public void map(KeyValue<V> v, AsyncCallback<T,E> cb);
}
如何使參數可選? 如果用戶只提供第一個參數,我如何給參數默認值?
使用 TypeScript,看起來像:
public static interface Mapper<V,T = any,E = any> {
public void map(KeyValue<V> v, AsyncCallback<T,E> cb);
}
因此,如果用戶不提供 T 和 E,則默認為any 。 有沒有辦法用 Java 做到這一點?
我看到了兩種解決方法(或者至少是解決問題的方法):
第一種方法是用所有參數實現一個方法,如果不需要,則傳遞null
而不是參數。 然后在您的方法體內處理它。 看起來應該像這樣:
public void myMethod(Sometype param1, Sometype param2, Sometype param3) { //Test if your paramaters are null or not then do what you want }
您可以像這樣調用您的方法(例如,如果不需要第二個參數): myInstance.myMethod(param1, null, param2);
您可以這樣做,但是我不建議您使用此技巧,因為它對用戶而言是違反直覺的,並且您的方法將是冗長且“不干凈的” ...
還有第二種方法。 即使它比TypeScript或Kotlin更為冗長,也可以使用所需的參數簡單地定義幾種方法。 例如,一個僅帶有第二個參數的方法,一個帶有第一個和第三個參數的方法,等等。。。這只是基本的方法重載 ,但是效果很好! 我認為這是最“ java友好”的方法之一。
希望對你有幫助
與許多語言一樣,Java中沒有可選或漸進式的輸入。 輸入規則可能很復雜。 也沒有默認類型參數,但這似乎並不是這里的主要問題。
在您的情況下,看起來像使鍵入更加易於客戶使用就可以解決問題,而不必走得更遠。 我假設AsyncCallback
的E
用於“ exception”,而T
是GWT的AsyncCallback
中的方法參數。
public static interface Mapper<V,T,E> {
public void map(KeyValue<V> v, AsyncCallback<? super T,? extends E> cb);
}
這允許任何特定的Mapper
采取任何適用的AsyncCallback
。
我們可以更明確地說明異常-如果需要在任何地方定義throws
則非常有用。
public static interface Mapper<V,T,E extends Throwable> {
如果對Mapper
的引用可以采用任何AsyncCallback
,請為某些V
聲明其類型為Mapper<V,Object,Throwable>
。
如果您迫切希望使用簡短的Mapper
以及簡潔的聲明,可以引入適配器。
public class MapperAny<V> implements Mapper<V,Object,Throwable> {
private final Mapper<V,Object,Throwable> target;
// A static creation method would be nicer, but ctor conventional.
public MapperAny(Mapper<V,Object,Throwable> target) {
this.target = target;
}
public void map(KeyValue<V> v, AsyncCallback<T,E> cb) {
target.map(v, cp);
}
// unwrap
public Mapper<V,Object,Throwable> mapper() {
return target;
}
}
如果您想為AsyncCallback
使用相同的東西, AsyncCallback
困難一些。 沒有Object
表示相反的Object
(即null
的類型)。
我會說不。 當Java的所有變量都設置為特定類型並且永不更改時,Java會喜歡它。 如果要找到最大的靈活性,請嘗試找到最大可能的超類,例如T = Object和E = Object。 稍后,當您需要使用該對象時,可以將其轉換為所需的對象? 也許?
如果您的想法大致相同:
然后,以下是解決此問題的方法。 因為我認為不允許將參數設為可選。
interface InterfaceA<T, T> {
boolean myMEthod(T clazz, UserRef user, String type, T clazz2) {
return false;
}
}
interface InterfaceB<T> extends InterfaceA<T, T> {
default boolean myMEthod(T clazz, UserRef user, String type) {
return myMEthod(clazz, user, type, clazz);
}
}
這使您可以在要跳過參數的任何地方實現InterfaceB
。 您可以兩次傳遞相同參數(相同類型),傳遞null
或某個默認值。
希望這對您有用。
你不能用一個 class 來解決它,但你可以使用 inheritance 部分解決它。 說你有
interface Mapper<V,T,E> {
public void map(KeyValue<V> v, AsyncCallback<T,E> cb);
}
然后,您可以擁有專門用於此的接口,如下所示:
interface MapperWithObjectValue<T,E> extends Mapper<Object, T, E> {
}
interface MapperWithObjectResult<V,E> extends Mapper<V, Object, E> {
}
等等
這種方式並不是很有用,因為用戶也可以將 Object 作為類型參數傳遞,但它確實有用於追溯生成接口的用途。 說你有
interface Foo {
Object getFoo();
}
然后你意識到你希望返回類型是一個泛型類型,但是你已經提交了這個接口作為你穩定的 API 的一部分。 然后,您可以通過 inheritance 使用專業化來解決它,如下所示:
interface GenericFoo<T> {
T getFoo();
}
interface Foo extends GenericFoo<Object> {
}
現有代碼可以像以前一樣繼續使用Foo
,而需要不同返回類型的代碼可以改用GenericFoo
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.