可选或默认的通用参数

时间:2019-01-29 06:04:17

标签: java typescript generics optional-typing gradual-typing

说我有3个通用参数:

  public static interface Mapper<V,T = any,E = any> {
    public void map(KeyValue<V> v, AsyncCallback<T,E> cb);
  }

如何使参数可选?如果用户仅提供第一个参数,如何给参数提供默认值?

使用TypeScript,如下所示:

var form_api = $("#apiForm");
$(form_api).submit(function(event) {
   /* stop form from submitting normally */
   event.preventDefault();

   /* Get input values from form */
   var formData = prepFormData("#apiForm");
}

因此,如果用户不提供T和E,则默认为 any 。有没有办法用Java做到这一点?

4 个答案:

答案 0 :(得分:2)

我看到了两种解决方法(或者至少是解决问题的方法):

  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友好”的方法之一。

希望我能帮助您

答案 1 :(得分:2)

与许多语言一样,Java中没有可选或渐进式输入。输入规则可能很复杂。也没有默认类型参数,但这似乎并不是这里的主要问题。

在您的情况下,看起来像使键入变得更加易于客户端使用即可解决问题,而不必走得更远。我假设E中的AsyncCallback是“ 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,请为某些Mapper<V,Object,Throwable>将其声明为V类型。

如果您迫切希望使用简明的声明形式的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使用相同的东西,则要困难一些。 Objectnull的类型)没有明显的对立面。

答案 2 :(得分:1)

我会拒绝。当Java的所有变量都设置为特定类型并且永不更改时,Java会喜欢它。如果要找到最大的灵活性,请尝试找到最大可能的超类,例如T = Object和E = Object。稍后,当您需要使用该对象时,可以将其转换为所需的对象?也许吗?

答案 3 :(得分:1)

如果您的想法大致相同:

  • 具有采用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或一些默认值。
希望这对您有用。