如何强制Java为方法调用的参数之一接受条件类型?

如何强制Java为方法调用的参数之一接受条件类型?,java,conditional-operator,overloading,variable-types,Java,Conditional Operator,Overloading,Variable Types,这个问题很难表达,所以我将不得不使用一些代码示例。基本上,我有一个(重载)方法,它接受3个参数,最后一个参数我重载了。如中所示,有时最后一个参数是字符串,有时是双精度,等等。我想使用三元条件表达式作为最后一个参数调用此方法,以便根据特定值,它将传递双精度或字符串。这里有一个例子 重载的方法头: writeToCell(int rowIndex, int colIndex, double value) writeToCell(int rowIndex, int colIndex, String

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

重载的方法头:

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)
MyType类型中的writeToCell(int,int,double)方法不适用 用于参数(int、int、Object&compariable&Serializable) Java似乎“不够聪明”(或者只是没有专门内置的功能),无法意识到这两个选项都有支持它的方法。我的问题是——有没有办法做到这一点?我知道我可以通过将double作为字符串传入来模拟它(例如,
writeToCell(2,4,myValue!=null?someDouble.toString():someString);
),但该方法需要将其作为双精度数据类型接收


逻辑告诉我,没有办法强迫Java接受这个语句。。。但它值得一试,因为它将为我带来更清晰的代码。有人知道这样做的方法吗?

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

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

并将
writeToCell
方法更改为接受参数
(int,int,Object)
方法调用在编译时静态解析,而不是在运行时动态解析。因此,编译器正在查找与该表达式中两个可能参数匹配的类型,如您所见

您可以做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”。它是静态的。

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

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

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

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

谢谢大家的建议和解释

我的一位同事查看了我的代码,并提出了我实现的解决方案。我在double方法的开头插入了以下代码:

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

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

三元操作的返回类型被上溯到java.lang.Object,作为String和autoboxed 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;
 }
}

不是真的。在这些位置上可以有不同的类型。试试看!我有,但在过去;这在Java 5或Java 6中是新出现的吗?自从Java 5中引入自动装箱以来,所有类型都可以转换为对象-以前确实不是这样,三元运算符中的原语和引用类型混合是编译时错误。@Michael:谢谢。。。你证明了我不是疯子。方法调用是在运行时动态解析的(否则,重写方法将不起作用)。这只是在编译时发生的重载方法之间的选择。我确实想到了这个解决方案,但是重载方法根据数据类型做的事情略有不同,所以我不能只创建一个通用对象方法。这就是为什么我首先有不同的方法,然后你必须让你的对象接受方法重新修补到各个方法,或者按照tloach说的去做。@Jonathan:明白了;静态方法dispathc也是编译时的。但对于最常见的情况(非重载实例方法),您仍然是错的。@Jonathan-实际上我最终使用了一种不同的解决方案-见下文,我将其作为答案发布。谢谢你的帮助!对我在一行中有一堆方法调用,它们必须做同样的事情(并且由于各种原因不能在一个循环中),写出来会使代码更长、更混乱。如果这会使代码更长、更混乱,那么您需要进行一些严肃的重构!不能将本机类型与对象混合使用。将它们装箱(或者让编译器来做)。