2

コンパイル エラーが発生する理由がわからないジェネリックを含むコードを使用しています。

  public static void main(String[] args) {

    System.out.print("s");
    setInteger(prepareNumber("1")); // Error here! solved by casting: setInteger((Integer)prepareNumber("1"))
    Integer c = prepareInteger("1");
    System.out.print(c);

  }

  public static Integer prepareInteger(Object number) {
    return prepareNumber(number).intValue();
  }

  private static <T extends Number> T prepareNumber(Object number) {

    T returnValue = null;

    // handle a blank number
    if (number == null || !NumberUtils.isNumber(number.toString())) {
      returnValue = null;
    } else {
      if (number.toString().contains(".")) {
        returnValue = (T) Double.valueOf(number.toString());
      } else {
        returnValue = (T) Integer.valueOf(number.toString());
      }
    }

    return returnValue;
  }

  private static void setInteger(Integer a){    
  }

キャストを行うだけでこれを修正するのは簡単ですが、ジェネリックはメソッドが整数を必要とすることを検出し、スーパータイプではなくそのような戻り値を提供する必要があるため、望ましくありません。

PS: 解析コードは気にしないでください。ただのテストです。

ありがとう!

4

2 に答える 2

1

prepareNumber("1")この場合、コンパイラは、返されるはずの型を推測できません。結果を一時変数に入れることで、正しく推論することができます。

Integer value = prepareNumber("1");        
setInteger(value);

parseNumberまたは、クラスの静的メソッドである場合は、YourClass次のように期待する型をコンパイラに明示的に伝えることができます。

setInteger(YourClass.<Integer>prepareNumber("1"));

または、コンパイラを支援するためにメソッド シグネチャを変更しても問題ない場合は、次のようにします。

setInteger(prepareNumber("1", Integer.class));

private static <T extends Number> T prepareNumber(Object number, Class<T> classType) {
   ....
}
于 2012-10-31T16:55:01.733 に答える
0

prepareNumberメソッドは、IntegerのスーパークラスであるNumberの型を返しますが、setIntegerはIntegerを受け入れており、このシナリオでは暗黙的にキャストされていません。

于 2012-10-31T16:50:12.810 に答える