繁体   English   中英

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

[英]How can I force Java to accept a conditional type for one of the parameters of a method call?

这个问题很难表达,因此我将不得不使用一些代码示例。 基本上,我有一个(重载)方法,该方法带有3个参数,最后一个参数已重载。 例如,有时最后一个参数是String ,有时它是double ,等等。我想使用三元条件表达式作为最后一个参数来调用此方法,以便根据某个值,它将传递double或a串。 这是一个例子

重载的方法标题:

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

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

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

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

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

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

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

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

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

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

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

我知道此实现可能并不总是最好的主意,但是由于在将double值传递给此方法时几乎总是需要检查null,因此在这种情况下最有意义。 这样,我不必每次都重复检查代码(如果/三元语句),并且我的方法调用更加简洁。

三元运算的返回类型被转换为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;
 }
}

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM