4

基本上我想要的是两个返回值略有不同的公共方法来调用相同的方法来完成所需的任何工作。它们都返回私有方法的返回值,但是私有方法将知道如何根据调用它的公共方法返回正确的值。

示例方法:

public Map<Type1, Type3> doSomething1();
public Map<Type2, Type3> doSomething2();

private Map<Type1/Type2, Type3> doSomething(); 

因此,在上面的示例中,doSomething() 返回 Type1 或 Type2 作为 Map 的键类型,具体取决于调用它的公共方法。它将能够执行简单的检查,并使用正确类型的对象填充地图。

也许这可以通过一些巧妙的 Java 反射来完成?我不知道。这一切看起来都很狡猾,所以如果有更好的方法来解决这个问题,我会全力以赴。

4

7 回答 7

8

我强烈建议在这里避免使用反射魔力。一个函数必须正确地做一件事,并且不能依赖于谁调用它。

更好的方法是将 doSomething() 重构为更小的函数,创建两个名为 doSomethingFor1() 和 doSomethingFor2() 的新函数。这两个函数都可以重用旧 doSomething() 的重构部分。

现在调用 doSomething1() 并使用 doSomethingFor1()。

同样,doSomething2() 应该使用 doSomethingFor2()。

干杯,

jrh

于 2009-05-28T05:51:59.313 回答
3

请注意: 我误解了这个问题,所以这个答案与问题的要求相反。我将把它作为社区 wiki 留作参考,但这并不能回答最初的问题。

Type1如果和Type2调用有一个共同的子类型SuperType,那么说第一个类型是? extends SuperType可行的。

这是一个使用IntegerandDouble作为两种类型的小例子,它们的共同祖先是Number

private Map<Integer, String> doSomethingForInteger() {
  HashMap<Integer, String> map = new HashMap<Integer, String>();
  map.put(10, "Hello");
  return map;
}

private Map<Double, String> doSomethingForDouble() {
  HashMap<Double, String> map = new HashMap<Double, String>();
  map.put(3.14, "Apple");
  return map;
}

public Map<? extends Number, String> doSomething(boolean b) {
  if (b)
    return doSomethingForInteger();
  else
    return doSomethingForDouble();
}

在这里,该方法将根据传入的 sdoSomething返回两种类型的s。要么要么由方法返回。HashMapbooleanHashMap<Integer, String>HashMap<Double, String>doSomething

实际上调用doSomethingaboolean可以这样完成:

Map<? extends Number, String> map1 = doSomething(true);
Map<? extends Number, String> map2 = doSomething(false);

map1会结束Hashmap<Integer, String>,而map2会得到Hashmap<Double, String>

于 2009-05-28T06:15:53.097 回答
1

如果一切都失败了,让私有方法返回 Object 并在公共方法中使用强制转换。

于 2009-05-28T05:49:20.097 回答
1

第一个问题是为什么你需要这个精确的结构。

但安全的方法是让它返回

public Map<Object, Type3> doSomething();

如果 Type1 和 Type2 没有共同的超类型。如果你确实有一个通用的超类型,你可以使用它来代替对象。

最好重构不需要的代码。

于 2009-05-28T05:53:50.450 回答
1

我需要您的问题中缺少的一些信息,例如如何实例化 type1 和 type 2,因为您不能直接从任意类型参数进行实例化。现在,我们假设有一些公共数据用于实例化 type1 和 type2。否则,没有充分的理由对两种方法都使用一种方法。在后一种情况下,这意味着一个函数根据类型做两件不同的事情,这是不好的编程。如果您要拥有直接基于调用方法的逻辑,只需拥有两个私有方法并重构出常用的东西。

如果您仅根据某些数据进行不同的实例化,那么最简单的方法是声明一个私有内部接口:

private interface Instantiator<T> {

     T getNew(Data data);        

}

现在,假设您可以实例化您的类型,您实际上可以使用它:

private <T> Map<T,Type3> doSomething(Instantiator<T> instantiator) {...}

作为方法签名,并让公共方法使用适当的 Instantiator 实现调用它。

于 2009-05-28T06:13:20.713 回答
0

您绝对可以通过使用反射分析堆栈来做到这一点。但我会尽量避免它,并且:

  • 返回基本类型(或对象)并在调用者中正确转换,无论如何你都必须这样做
  • 将参数传递给私有方法,以某种方式指示要做什么并返回
于 2009-05-28T05:52:40.823 回答
0

您可以模拟 Closure 的想法:

interface MappingClosure {
    public void map(Map, MapProvider);
}


class Caller implements MappingClosure {
     public void map(final Map MAP, final MapProvider CALLEE) {
         this.MAP = specialise(MAP);
         // CALLEE USED AS KEY
     }
}


class MapProvider {  
    public Map getMap(final MappingClosure CALLER) {
        return CALLER.map(mapInstance, this);
    }
}

然后修改数据以适应对象的需要与使用需要它的对象的方法不同。

于 2009-05-28T06:33:24.753 回答