[英]How can I force Java to accept a conditional type for one of the parameters of a method call?
This question is hard to phrase, so I'm going to have to use some code samples. 这个问题很难表达,因此我将不得不使用一些代码示例。 Basically, I have an (overloaded) method that takes 3 parameters, the last of which I overloaded.
基本上,我有一个(重载)方法,该方法带有3个参数,最后一个参数已重载。 As in, sometimes the last parameter is a
String
, sometimes it's a double
, etc. I want to call this method using a ternary conditional expression as the last parameter, so that depending on a certain value, it will pass either a double or a String. 例如,有时最后一个参数是
String
,有时它是double
,等等。我想使用三元条件表达式作为最后一个参数来调用此方法,以便根据某个值,它将传递double或a串。 Here's an example... 这是一个例子
Overloaded method headers: 重载的方法标题:
writeToCell(int rowIndex, int colIndex, double value)
writeToCell(int rowIndex, int colIndex, String value)
What I'm trying to do: 我正在尝试做的是:
writeToCell(2, 4, myValue != null ? someDouble : someString);
This, however, causes a compilation error: 但是,这会导致编译错误:
The method writeToCell(int, int, double) in the type MyType is not applicable
for the arguments (int, int, Object&Comparable<?>&Serializable)
It seems that Java isn't "smart enough" (or just doesn't have the functionality built in on purpose) to realize that either option has a method that supports it. 似乎Java不够“聪明”(或者只是没有故意内置的功能),无法意识到这两个选项都有支持它的方法。 My question is - is there any way to do this?
我的问题是-有没有办法做到这一点? I know I can sort of simulate it by passing in the double as a String (eg
writeToCell(2, 4, myValue != null ? someDouble.toString() : someString);
), but the method needs to receive it as a double data type. 我知道我可以通过将double作为字符串传递来进行模拟(例如,
writeToCell(2, 4, myValue != null ? someDouble.toString() : someString);
),但是该方法需要以double形式接收它数据类型。
Logic tells me that there's no way to force Java to accept this statement... But it's worth a try, as it will result in a lot clearer code for me. 逻辑告诉我,没有办法强迫Java接受此语句……但这是值得尝试的,因为它将为我带来更清晰的代码。 Anyone know of a way to do this...?
有人知道这样做的方法吗?
Method calls are resolved statically, at compile time, not dynamically, at runtime. 方法调用是在编译时静态解决的,而不是在运行时动态解决的。 Therefore, the compiler is looking for the type that matches both of the possible arguments in that expression, as you can see.
因此,如您所见,编译器正在寻找与该表达式中两个可能的参数都匹配的类型。
You could do what the SDK does a lot of, and define your method as 您可以执行SDK的大部分工作,然后将您的方法定义为
writeToCell(int rowIndex, int colIndex, Object value)
and then have the first line be 然后将第一行
final String repr = String.valueOf(value);
There are plenty of other solutions, but it's best not to overthink this. 还有许多其他解决方案,但是最好不要对此过度考虑。
Demonstration: 示范:
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);
}
If method lookup were dynamic, then the you'd see "frobs" both times. 如果方法查找是动态的,那么两次您都将看到“ frobs”。 It's static.
它是静态的。
Is there any particular reason not to just write it out? 有什么特别的理由不把它写出来吗?
if (myValue == null)
writeToCell(2, 4, someString);
else
writeToCell(2, 4, someDouble);
I suspect that it chokes up because the type of object (and hence overloaded version which should be called) cannot be determined at compile time. 我怀疑它阻塞了,因为无法在编译时确定对象的类型(因此应该调用重载版本)。 It's similar to:
它类似于:
Object o = myValue != null ? someDouble : someString;
writeToCell(2, 4, o);
Thanks everyone for all your suggestions and explanations. 感谢大家的所有建议和解释。
A coworker of mine took a look at my code and suggested a solution that I implemented. 我的一位同事查看了我的代码并提出了我实施的解决方案。 I inserted the following code into the beginning of my double method:
我在double方法的开头插入了以下代码:
if(value == null){
writeToCell(rowIndex, colIndex, someString)
}
else{
...method body...
}
I know that this implementation might not always be the best idea, but since I almost always need to check for null when passing a double value to this method, it makes the most sense in this situation. 我知道此实现可能并不总是最好的主意,但是由于在将double值传递给此方法时几乎总是需要检查null,因此在这种情况下最有意义。 This way I don't have to repeat the check code (if / ternary statement) each time, and my method calls are much cleaner.
这样,我不必每次都重复检查代码(如果/三元语句),并且我的方法调用更加简洁。
The return type from the ternary operation is being upcast to java.lang.Object, as the common superclass class of both String and the autoboxed double, so you would have to provide the method signature for the object, and then use that to make the appropriate cast and call the relevant method: 三元运算的返回类型被转换为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;
}
}
The ternary operator has to return the same type from the "then" or "else" clause. 三元运算符必须从“ then”或“ else”子句返回相同的类型。 If you can deal with
Double
instead of double
, then you could try 如果您可以处理
Double
而不是double
,那么您可以尝试
Object o = (myValue != null ? someDouble : someString);
writeToCell(2, 4, o);
and change the writeToCell
method to accept arguments (int, int, Object)
. 并更改
writeToCell
方法以接受参数(int, int, Object)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.