根据调用方法更改返回类型

发布于 2024-07-22 08:13:38 字数 472 浏览 10 评论 0原文

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

示例方法:

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

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

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

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

Basically what I want, istwo public methods with slightly different return values to call the same method to do whatever work is needed. They both return the return value of the private method, however the private method will know how to return the correct value depending on the public method that called it.

Example methods:

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

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

So, in the above example, doSomething() returns either Type1 or Type2 as the Map's key-type, depending on which public method called it. It would be able to perform a simple check, and populate the map with objects of the correct type.

Maybe this can be done through some clever Java reflection? I'm not sure. It all seems pretty dodgy, so if there's a much better way to go about this, I'm all ears.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

迷荒 2024-07-29 08:13:38

我强烈建议在这里避免使用反射魔力。 函数必须正确地完成一件事,并且不能取决于调用它的人。

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

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

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

干杯,

jrh。

I strongly suggest that reflection-mojo should be avoided here. A function must do one thing propertly, and must not depend on who call it.

A better way to do the same would be to refactor doSomething() into smaller functions, create two new functions called doSomethingFor1() and doSomethingFor2(). Both these functions can reuse the refactored parts of the old doSomething().

Now have doSomething1() call and use doSomethingFor1().

Likewise, doSomething2() should use doSomethingFor2().

cheers,

jrh.

听你说爱我 2024-07-29 08:13:38

请注意: 我误解了这个问题,所以这个答案与问题的要求相反。 我会将其保留为社区 wiki 供参考,但这并不能回答原始问题。

如果 Type1Type2 存在一个名为 < code>SuperType,那么说第一个类型是? 扩展 SuperType 可以工作。

下面是一个使用 IntegerDouble 作为两种类型,并将它们的共同祖先作为 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();
}

这里, doSomething< /code> 方法将根据传入的 boolean 返回两种类型的 HashMapHashMap 或 < code>HashMapdoSomething 方法返回。

实际上,使用 boolean 调用 doSomething 可以这样完成:

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

map1 最终会得到 HashmapHashmapcode>,而map2将得到Hashmap

Please note: I've misunderstood the question, so this answer is opposite of what the question is as asking for. I will leave this up for reference as community wiki, but this does not answer the original question.

If there were a common subtype to Type1 and Type2 called SuperType, then saying that the first type is ? extends SuperType would work.

Here's a little example that uses Integer and Double as the two types, and their common ancestor as 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();
}

Here, the doSomething method will return two types of HashMaps depending on the boolean that is passed in. Either HashMap<Integer, String> or HashMap<Double, String> is returned by the doSomething method.

Actually calling up doSomething with a boolean can be accomplished like this:

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

map1 will end up with Hashmap<Integer, String>, while map2 will get Hashmap<Double, String>.

娇纵 2024-07-29 08:13:38

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

If everything else fails, let the private method return Object and use casts in the public methods.

桜花祭 2024-07-29 08:13:38

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

让它返回

public Map<Object, Type3> doSomething();

但安全的方法是,如果 Type1 和 Type2 没有共同的超类型,则 。 如果您确实有一个通用的超类型,则可以使用它来代替对象。

最好重构不需要的代码。

The first question is why you need this exact structure.

But the safe way is to make it return

public Map<Object, Type3> doSomething();

if there is no common supertype for Type1 and Type2. If you do have a common super type, you could use that instead of object.

It would be best to refactor the code that this isn't required.

夜声 2024-07-29 08:13:38

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

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

private interface Instantiator<T> {

     T getNew(Data data);        

}

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

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

作为方法签名,并且让公共方法使用适当的实例化器实现来调用它。

I need a bit of info that is missing from your question, as for example how type1 and type 2 are instantiated, since you can't instantiate directly from arbitrary type parameters. Now, we assume there is some common data used to instantiate both type1 and type2. Otherwise, there is no good reason to use one method for both. In the latter case, this would mean one function doing two separate things based on type, which is bad programming. If you're going to have logic which is directly based on the calling method, simply have two private method and refactor out the common stuff.

If you do only the instantiation differently, based on some data, the easiest way to do this would be to declare a private inner interface:

private interface Instantiator<T> {

     T getNew(Data data);        

}

Now, assuming that you can instantiate your types, you can actually use this:

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

as a method signature, and have the public methods call it with the appropriate Instantiator implementation .

嘿嘿嘿 2024-07-29 08:13:38

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

  • 返回基类型(或对象)并在调用者中正确地转换它,无论如何你都必须这样做
  • 将参数传递给私有方法,以某种方式指示要做什么并返回

You can definitely do it by analyzing the stack using reflection. But I would try to avoid it and:

  • return base type (or object) and cast it properly in the caller, which you will have to do anyways
  • pass a parameter to the private method indicating somehow what to do and return
暮色兮凉城 2024-07-29 08:13:38

您可以对 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);
    }
}

然后修改数据以满足对象的需要与需要它的对象的方法不同。

You could model the idea of a 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);
    }
}

Then modifying the data to suit the objects needs are differed to a method withing the object that requires it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文