如何强制Java为某个方法调用的某个参数接受条件类型?
这个问题很难说,所以我将不得不使用一些代码示例。基本上,我有一个(重载)方法需要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接受这种说法......但值得一试,因为它会为我带来更多更清晰的代码。任何人都知道如何做到这一点......?
感谢大家的所有建议和解释。
我的一位同事看了看我的代码,并提出了我实施的解决方案。我插入下面的代码到我的双重方法的开头:
if(value == null){
writeToCell(rowIndex, colIndex, someString)
}
else{
...method body...
}
我知道,这个实现可能并不总是最好的主意,但因为我几乎总是需要检查空传递一个双精度值这个时方法,它在这种情况下最有意义。这样我就不必每次都重复检查代码(如果是/三态语句),而且我的方法调用更清晰。
三元运算符必须从“then”或“else”子句中返回相同的类型。如果你能处理Double
代替double
,那么你可以尝试
Object o = (myValue != null ? someDouble : someString);
writeToCell(2, 4, o);
,改变writeToCell
方法接受参数(int, int, Object)
。
不正确。你可以有不同于那些职位的类型。尝试一下! – 2010-03-04 19:49:50
我有,但过去;这是Java 5或6中的新功能吗? – Tenner 2010-03-04 19:52:58
自从在Java 5中引入自动装箱后,所有类型都可以转换为Object - 以前的情况确实不是这样,并且三元运算符中原始类型和引用类型的混合会导致编译时错误。 – 2010-03-04 20:13:23
在编译时静态解析方法调用,而不是在运行时动态解析。因此,编译器正在寻找匹配该表达式中可能参数的类型,如您所见。
你可以做的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-04 19:50:53
不正确;看演示。 – 2010-03-04 19:54:46
我的确想到了这个解决方案,但重载的方法根据数据类型做了稍微不同的事情,所以我不能只制作一个通用的Object方法。这就是为什么我首先有不同的方法 – froadie 2010-03-04 20:01:23
我怀疑它会窒息,因为在编译时无法确定对象的类型(以及因此应该调用的重载版本)。它类似于:
Object o = myValue != null ? someDouble : someString;
writeToCell(2, 4, o);
有什么特别的理由不写出来吗?
if (myValue == null)
writeToCell(2, 4, someString);
else
writeToCell(2, 4, someDouble);
是的。我有一堆方法调用必须做同样的事情(由于各种原因不能在一个循环中),写出来会使代码更长,更混乱。 – froadie 2010-03-04 19:51:39
如果_THAT_会让你的代码变得更长和更混乱,那么你需要做一些认真的重构! – 2010-03-05 13:09:29
三元操作的返回类型被上传到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;
}
}
您不能将本机类型与对象混合。把它们装箱(或者让编译器去做)。 – 2010-03-05 13:09:02