【问题标题】:Replacement for java reflection in method overloading方法重载中java反射的替换
【发布时间】:2023-03-07 23:12:01
【问题描述】:

我有以下类层次结构:

<code>
public interface Decorator <T> {
    T decorate(String data);
}
public class StringDecorator implements Decorator<String> {
    @Override
    public String decorate(String data) {
        return "Decorated Data";
    }
}
public class IntegerDecorator implements Decorator<Integer> {
    @Override
    public Integer decorate(String data) {
        return 0;
    }
}
public class MyPrint {
    public void printData(String data) {
        System.out.println("String Data: " + data);
    }
    public void printData(Integer data) {
        System.out.println("Integer Data: " + data);
    }
}
</code>

有了上面的结构,我想首先调用一些装饰器函数并将相同的结果传递给 printData 方法。目前,我可以在 java 反射的帮助下实现这一点,如下所示:

<code>
void callerFunction(Decorator decorator, MyPrint myPrint){
    // Below line would call appropriate decorator depending on injected type
    Object decoratedData = decorator.decorate("test");
    try {
        // Java reflection to figure out an appropriate overloaded method to be invoked
        myPrint.getClass().getMethod("printData", decoratedData.getClass()).invoke(myPrint, decoratedData);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
</code>

有没有更好的方法可以在不使用反射的情况下实现同样的效果?用例是根据装饰器返回的数据类型调用适当的 printData 重载函数(不使用 instanceOf 上的 if else)。

谢谢。

【问题讨论】:

  • 这肯定不是装饰器的正确实现,但好消息是,这个问题不需要装饰器。
  • 可能是访客的工作。
  • 是的,那里的命名约定可能不好。假设上述问题中的装饰器层次结构实际上以一种或另一种方式处理数据。可能是某种处理器。

标签: java reflection overloading


【解决方案1】:

我能想到两种解决方案。

首先,您不必为重载 printData 而烦恼,而是依赖于在每个类中定义一个合适的 toString 方法:

 public void printData(Object data) {
    System.out.println("Data: " + data);
}

其次,您可以使用泛型定义打印数据方法,例如在每个装饰器中

public interface Decorator <T> {
    T decorate(String data);
    void printData(T object);
}

或者等效地,您可以定义一个单独的 printData 接口,然后无论您的装饰器类如何创建,都必须创建一个相应的 printData 类。

【讨论】:

  • 感谢您的及时回复马特。第一个带有“对象”的方法在我的情况下不起作用,因为我想根据数据类型执行不同的操作。此外,正如您所说,对具有泛型的两个函数使用层次结构是可行的。但是想看看是否有一个可以为此使用重载的选项。因为我已经为 myPrint 设置了不同的层次结构,例如 mailPrint 和 filePrint。
  • 很公平。你在那种情况下有点卡住了。重载不会起作用,因为重载方法是在编译时根据对象类型确定的。由于编译器只有一个对象,它无法决定调用哪个方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-21
  • 2012-11-10
相关资源
最近更新 更多