简体   繁体   English

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

[英]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.

相关问题 如何强制java接受相同类型的泛型参数 - How to force java to accept the same type generic parameters 如何使方法接受Java中的类类型变量? - How can I make a method accept a class type variable in Java? 如何在方法调用中对参数类型使用继承? - How can I use inheritance for parameters type in a method call? 我如何强制 JSON 日期在 Java 中不接受整数 - How i can force JSON dates to not accept integer in java 如何强制Java的HttpClient接受无效的cookie? - How can I force Java's HttpClient to accept invalid cookies? 如何将方法限制为仅接受具有特定限制的参数? - How can I limit a method to only accept parameters with certain restrictions? 如何在Struts2中强制方法仅接受POST参数? - How to force a method to only accept POST parameters in Struts2? 如何在Java中扩展列表以存储其他元数据并强制其仅接受一种类型的对象? - How to extend a list in java to store additional metadata and force it to accept only one type of objects? ServerSocket接受方法 - 如何向下转换为子类类型? - ServerSocket accept method - How can I down cast to a subclass type? 如何测试Method是否接受参数类型? - How can I test if a Method will accept a parameter type?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM