簡體   English   中英

可選或默認的泛型參數

[英]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 做到這一點?

我看到了兩種解決方法(或者至少是解決問題的方法):

  1. 第一種方法是用所有參數實現一個方法,如果不需要,則傳遞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);

    您可以這樣做,但是我不建議您使用此技巧,因為它對用戶而言是違反直覺的,並且您的方法將是冗長且“不干凈的” ...

  2. 還有第二種方法。 即使它比TypeScript或Kotlin更為冗長,也可以使用所需的參數簡單地定義幾種方法。 例如,一個僅帶有第二個參數的方法,一個帶有第一個和第三個參數的方法,等等。。。這只是基本的方法重載 ,但是效果很好! 我認為這是最“ java友好”的方法之一。

希望對你有幫助

與許多語言一樣,Java中沒有可選或漸進式的輸入。 輸入規則可能很復雜。 也沒有默認類型參數,但這似乎並不是這里的主要問題。

在您的情況下,看起來像使鍵入更加易於客戶使用就可以解決問題,而不必走得更遠。 我假設AsyncCallbackE用於“ 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。 稍后,當您需要使用該對象時,可以將其轉換為所需的對象? 也許?

如果您的想法大致相同:

  • 具有采用3個(通用)參數的方法
  • 但有時您會希望它具有2個參數

然后,以下是解決此問題的方法。 因為我認為不允許將參數設為可選。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM