【问题标题】:Generic Method That takes unique parameter and returns unique parameters JavaJava 接受唯一参数并返回唯一参数的通用方法
【发布时间】:2017-07-06 22:59:18
【问题描述】:

我有一个要求,在函数中需要不同的参数并返回唯一的对象。所有这些函数都执行相同的操作。

即。

public returnObject1 myfunction( paramObject1 a, int a) {
returnObject1 = new returnObject1();
returnObject1.a = paramObject1.a;
return returnObject1;
}

public returnOject2 myfunction( paramObject2 a, int a){
 returnObject2 = new returnObject2();
 returnObject2.a = paramObject2.a;
 return returnObject2;
}

正如您在上面看到的,这两个函数都执行相同的任务,但它们将不同的参数作为输入并返回不同的对象。

我想尽量减少编写执行相同任务的不同函数。

是否可以为此编写一个通用方法,可以根据对函数的调用替换参数?

paramObject 和 returnObject 基本上是两个具有不同变量的类。它们彼此无关。

我的目标是我不想做函数重载,因为函数做几乎相同的工作。我想要一个可以处理不同输入和不同返回输出的函数。

我的目标是做这样的事情(如果可能的话):

public static < E > myfunction( T a, int a ) {
  // do work
}

返回类型 E 和输入 T 可以保持变化。

【问题讨论】:

  • 如果没有关于 paramObject1 和 paramObject2 是什么的更具体信息,这很难回答。如果它们是相似的类型,也许您应该保留这两个公共方法,将公共代码移动到新的私有方法,并让每个方法调用该私有方法。
  • “paramObject”和“returnObject”是如何连接的?
  • 您的意思是处理方式相同,但对象类型不同?如果是这样,并且如果它们共享相同的方法名称,您可以编写类似 public T myfunction(T param, int a) 的内容
  • 也许 public Object[] myFunction(int a , Object... abstractObjectArray) 听起来也很有帮助
  • 现在看来@Radiodef 所说的对我来说很有意义。我必须创建和接口或抽象类来处理这个。

标签: java generics java-8 generic-method


【解决方案1】:

您可以使用第三种apply 方法来删​​除代码重复,在此方法中将创建和初始化与apply 方法分开。并且不关心使用哪种类型的T。例如:

returnObject1 myfunction(paramObject1 a, int b) {
    return apply(returnObject1::new, b, value -> {
        //uses paramObject1
        //populates returnObject1
        //for example:
        value.foo = a.bar;
    });
}

returnOject2 myfunction(paramObject2 a, int b) {
    return apply(returnOject2::new, b, value -> {
        //uses paramObject2 
        //populates returnObject2
        //for example:
        value.key = a.value;
    });
}

<T> T apply(Supplier<T> factory, int b, Consumer<T> initializer) {
    T value = factory.get();
    initializer.accept(value);
    //does work ...
    return value;
}

注意这2个myfunction是可选的,你可以把它们从你的源代码中去掉,然后直接调用apply方法,例如:

paramObject2 a = ...;

returnObject2  result = apply(returnOject2::new, 2, value -> {
    //for example:
    value.key = a.value;
});

【讨论】:

  • 我想省去写两个函数。而是使用一个接受不同参数的函数。
  • @AJRoot 也许 apache beanutils 满足您的需求。您没有提供足够的信息,所以我的回答也是 abstract... :),请注意,上面的 2 个 myfunction 方法是可选的,您也可以删除它们。
【解决方案2】:

创建interface Foo 并在paramObject1paramObject2 类中实现这个interface。现在你的方法应该是这样的:

public Foo myFunction(Foo foo, int a){
    //Rest of the code.
    return foo;
}

【讨论】:

  • 我也在考虑这些思路,并为通用性创建一个抽象基类。
  • 这是有道理的,但我想知道是否还有其他方法。我想避免创建一个新接口来处理这个问题,因为我有很多不断变化的对象。
  • 我认为你正在做某事。挑战是当Foo 是一个接口时,你不能做new Foo()。必须找到解决方案。