5

我有一个字符串,它可以是 Double 或 Integer 类型或其他类型。我首先需要创建一个 Double 或 Integer 对象,然后将其发送到重载方法。到目前为止,这是我的代码;

public void doStuff1(object obj, String dataType){

 if ("Double".equalsIgnoreCase(dataType)) {
        doStuff2(Double.valueOf(obj.toString()));
    } else if ("Integer".equalsIgnoreCase(dataType)) {
        doStuff2(Integer.valueOf(obj.toString()));
    }

 }

 public void doStuff2(double d1){
   //do some double related stuff here
 }

 public void doStuff2(int d1){
   //do some int related stuff here
 }

我想在没有 if/else 的情况下这样做,像这样;

Class<?> theClass = Class.forName(dataType);

问题是 'theClass' 仍然不能转换为 double 或 int。如果有任何想法,我将不胜感激。谢谢。

找到一个相关的线程;Java中的重载和多分派

4

4 回答 4

4

这不仅仅是处理原始类型的问题。

调用哪个方法是在编译时决定的,也就是说,如果您希望能够根据参数的类型调用不同的方法,您将需要多次调用(即您需要 if-construct)。

换句话说,即使doStuff2IntegerandDouble作为参数它也不起作用(你的代码基本上和它一样好)。

(简单地说,这是因为 Java 有单次调度。要模拟多次调度,您需要使用条件语句或访问者模式。)

于 2012-05-02T10:39:38.407 回答
1

正如 aioobe 所说,重载方法之间的选择是在编译时根据参数的静态类型进行的。

如果要在运行时模拟重载选择,则需要对不同的可能方法进行一些复杂的运行时分析。它会是这样的:

  1. 获取声明的类的所有声明方法doStuff2
  2. 过滤掉名字不是的方法doStuff2
  3. 从参数值的(动态)类型中过滤掉参数类型不能赋值的方法。
  4. 在剩余的方法中,选择最匹配的一种……注意将“关系”处理为模棱两可。

这对代码来说会很棘手,如果你还要处理原始类型,那就更棘手了。它还会使方法调用变得昂贵。


坦率地说,某种硬接线调度要简单得多。如果您不喜欢 if / else 测试(或在 Java 7 中打开字符串),那么您可以执行类似的操作。

Map<String, Operation> map = ...
map.put("Double", new Operation(){
    public void doIt(Object obj) {
        doStuff2((Double) obj);
    }});
map.put("Integer", new Operation(){
    public void doIt(Object obj) {
        doStuff2((Integer) obj);
    }});
...
map.get(typeName).doIt(obj);

...至少允许您动态地“插入”对新类型的支持。

于 2012-05-02T11:00:28.360 回答
1

由于方法调用是在编译时决定的,正如另一个答案告诉你的那样,重载对你不起作用。我认为这个问题可以通过继承来解决。因此,您编写一个基类yourMethod()并在派生类中覆盖它。

于 2012-05-02T11:00:31.857 回答
1

如果你求助于反射,你只需要专门处理原始类型。因此,您的技术可以工作,但需要添加一些明确的测试。如果您需要反思性地找到接受原语的方法double,请使用double.class.

于 2012-05-02T11:17:04.493 回答