2

这个问题很难说,所以我将不得不使用一些代码示例。基本上,我有一个(重载)方法,它需要 3 个参数,我重载了最后一个参数。如,有时最后一个参数是 a String,有时是 adouble等。我想使用三元条件表达式作为最后一个参数来调用此方法,以便根据某个值,它将传递一个双精度或字符串。这是一个例子......

重载的方法头:

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 还不够“聪明”(或者只是没有故意内置的功能)来实现任何一个选项都有支持它的方法。我的问题是 - 有没有办法做到这一点?我知道我可以通过将双精度作为字符串(例如writeToCell(2, 4, myValue != null ? someDouble.toString() : someString);)传递来模拟它,但是该方法需要将其作为双精度数据类型接收。

逻辑告诉我,没有办法强制 Java 接受这个声明......但值得一试,因为它会为我带来更清晰的代码。任何人都知道这样做的方法...?

4

6 回答 6

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”。它是静态的。

于 2010-03-04T19:47:53.690 回答
3

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

if (myValue == null)
  writeToCell(2, 4, someString);
else
  writeToCell(2, 4, someDouble);
于 2010-03-04T19:49:39.340 回答
1

三元操作的返回类型被向上转换为 java.lang.Object,作为 String 和自动装箱双精度的公共超类,因此您必须提供对象的方法签名,然后使用它来制作适当的演员并调用相关的方法:

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;
 }
}
于 2010-03-04T20:09:51.827 回答
0

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

Object o = myValue != null ? someDouble : someString;
writeToCell(2, 4, o);
于 2010-03-04T19:49:01.253 回答
0

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

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

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

我知道这种实现可能并不总是最好的主意,但是由于在将双精度值传递给此方法时我几乎总是需要检查 null,因此在这种情况下最有意义。这样我就不用每次都重复检查代码(if/三元语句)了,我的方法调用也干净多了。

于 2010-03-04T20:06:42.163 回答
-1

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

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

并更改writeToCell方法以接受参数(int, int, Object)

于 2010-03-04T19:47:44.413 回答