簡體   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