2

这个问题很难说,所以我将不得不使用一些代码示例。基本上,我有一个(重载)方法需要3个参数,最后一个我超载。和in一样,有时最后一个参数是String,有时候是double等等。我想用三态条件表达式作为最后一个参数来调用这个方法,所以根据某个值,它会传递一个double或者一个串。下面是一个例子...如何强制Java为某个方法调用的某个参数接受条件类型?

重载方法标题:

writeToCell(int rowIndex, int colIndex, double value) 

writeToCell(int rowIndex, int colIndex, String value) 

我想要做的事:

writeToCell(2, 4, myValue != null ? someDouble : someString); 

然而,这会导致编译错误:

The method writeToCell(int, int, double) in the type MyType is not applicable 
for the arguments (int, int, Object&Comparable<?>&Serializable) 

Java似乎并不“足够聪明”(或者只是没有专门构建的功能)来实现eit她的选择有一个支持它的方法。我的问题是 - 有没有办法做到这一点?我知道我可以通过以double形式传递字符串来进行模拟(例如writeToCell(2, 4, myValue != null ? someDouble.toString() : someString);),但该方法需要将其作为双数据类型接收。

逻辑告诉我,没有办法强制Java接受这种说法......但值得一试,因为它会为我带来更多更清晰的代码。任何人都知道如何做到这一点......?

+0

您不能将本机类型与对象混合。把它们装箱(或者让编译器去做)。 – 2010-03-05 13:09:02

回答

0

感谢大家的所有建议和解释。

我的一位同事看了看我的代码,并提出了我实施的解决方案。我插入下面的代码到我的双重方法的开头:

if(value == null){ 
    writeToCell(rowIndex, colIndex, someString) 
} 
else{ 
    ...method body... 
} 

我知道,这个实现可能并不总是最好的主意,但因为我几乎总是需要检查空传递一个双精度值这个时方法,它在这种情况下最有意义。这样我就不必每次都重复检查代码(如果是/三态语句),而且我的方法调用更清晰。

-1

三元运算符必须从“then”或“else”子句中返回相同的类型。如果你能处理Double代替double,那么你可以尝试

Object o = (myValue != null ? someDouble : someString); 
writeToCell(2, 4, o); 

,改变writeToCell方法接受参数(int, int, Object)

+0

不正确。你可以有不同于那些职位的类型。尝试一下! – 2010-03-04 19:49:50

+0

我有,但过去;这是Java 5或6中的新功能吗? – Tenner 2010-03-04 19:52:58

+0

自从在Java 5中引入自动装箱后,所有类型都可以转换为Object - 以前的情况确实不是这样,并且三元运算符中原始类型和引用类型的混合会导致编译时错误。 – 2010-03-04 20:13:23

4

在编译时静态解析方法调用,而不是在运行时动态解析。因此,编译器正在寻找匹配该表达式中可能参数的类型,如您所见。

你可以做的SDK做什么了很多,并定义你的方法

writeToCell(int rowIndex, int colIndex, Object value) 

,然后让第一线是

final String repr = String.valueOf(value); 

还有许多其他的解决方案,但它是最好不要过时这一点。

示范:

static class WrongAgain 
{ 
    void frob(final Object o) 
    { 
     System.out.println("frobo " + o); 
    } 

    void frob(final String s) 
    { 
     System.out.println("frobs " + s); 
    } 

} 

public static void main(final String[] args) 
{ 
    final WrongAgain wa = new WrongAgain(); 
    wa.frob("foo"); 
    Object o = "foo"; 
    wa.frob(o); 
} 

如果方法查找是动态的,那么你会看到 “frobs” 两次。它是静态的。

+1

方法调用*在运行时动态解析(否则,覆盖方法将不起作用)。这只是编译时发生的重载方法之间的选择。 – 2010-03-04 19:50:53

+0

不正确;看演示。 – 2010-03-04 19:54:46

+0

我的确想到了这个解决方案,但重载的方法根据数据类型做了稍微不同的事情,所以我不能只制作一个通用的Object方法。这就是为什么我首先有不同的方法 – froadie 2010-03-04 20:01:23

0

我怀疑它会窒息,因为在编译时无法确定对象的类型(以及因此应该调用的重载版本)。它类似于:

Object o = myValue != null ? someDouble : someString; 
writeToCell(2, 4, o); 
3

有什么特别的理由不写出来吗?

if (myValue == null) 
    writeToCell(2, 4, someString); 
else 
    writeToCell(2, 4, someDouble); 
+0

是的。我有一堆方法调用必须做同样的事情(由于各种原因不能在一个循环中),写出来会使代码更长,更混乱。 – froadie 2010-03-04 19:51:39

+0

如果_THAT_会让你的代码变得更长和更混乱,那么你需要做一些认真的重构! – 2010-03-05 13:09:29

0

三元操作的返回类型被上传到java.lang.Object,作为String和自动复制的double的公共超类,因此您必须为对象提供方法签名,然后使用即要进行相应的演员表并调用相关方法:

public class SoCast { 


public static void main(String[] args) { 
    SoCast sc = new SoCast(); 

    Double someDouble = 3.14; 
    String someString = "foo"; 
    String myValue = null; 

    sc.writeToCell(2, 4, myValue != null ? someDouble : someString); 

    myValue = "hello"; 

    sc.writeToCell(2, 4, myValue != null ? someDouble : someString); 

} 

private int writeToCell(int rowIndex, int colIndex, Object value) { 
    int result = -1; 
    if (value instanceof String) { 
    result = this.writeToCell(rowIndex, colIndex, (String) value); 
    } else if (value instanceof Double) { 
    result = this.writeToCell(rowIndex, colIndex, (Double) value); 
    } 
    return result; 
} 

private int writeToCell(int rowIndex, int colIndex, Double value) { 
    return 1; 
} 

private int writeToCell(int rowIndex, int colIndex, String value) { 
    return 5; 
} 
} 
相关问题