17

あなたがその方法を持っているとしましょう

  • しきい値と入力を取ります
  • 入力がしきい値よりも小さい場合、例外が発生します
  • それ以外の場合は入力を返します

次のようになります。

<N extends Number & Comparable<N>, S extends N> S ensureLessThan(N threshold, S input) {
    if (input.compareTo(threshold) >= 0) {
        throw new IllegalArgumentException("Input " + input + " is not less than " + threshold);
    }
    return input;
}

実行すると、このメソッドは:をスローしNoSuchMethodErrorます。

Exception in thread "main" java.lang.NoSuchMethodError: java.lang.Number.compareTo(Ljava/lang/Object;)I

冗長キャストのように見えるものを追加すると、機能します。

...
    if (((N) input).compareTo(threshold) >= 0) {
...

では、ここで何が起こっているのでしょうか。

更新:私のJavaバージョンは

java version "1.6.0_37"
Java(TM) SE Runtime Environment (build 1.6.0_37-b06-434-11M3909)
Java HotSpot(TM) 64-Bit Server VM (build 20.12-b01-434, mixed mode)

そして、これが実行可能な例です:https ://gist.github.com/4526536

4

3 に答える 3

7

コンパイラのバグだと思います。Number.compareTo(Object)存在するはずの、存在しないものに静的にバインドされていますComparable.compareTo(Object)

于 2013-01-13T21:23:23.447 に答える
5
if (threshold.compareTo(input) < 0) {

動作します。

確かにコンパイラエラーのようです。これが機能する理由は、コンパイラがComparableへのチェックキャストを生成するためです。逆にそれはしません。

ensureLessThan(Ljava/lang/Number;Ljava/lang/Number;)Ljava/lang/Number;
  L0
        LINENUMBER 11 L0
        ALOAD 1
        CHECKCAST java/lang/Comparable
        ALOAD 2
        INVOKEINTERFACE java/lang/Comparable.compareTo (Ljava/lang/Object;)I
        IFGE L1

ensureLessThan(Ljava/lang/Number;Ljava/lang/Number;)Ljava/lang/Number;
        LINENUMBER 11 L0
        ALOAD 1
        ALOAD 2
        INVOKEVIRTUAL java/lang/Number.compareTo (Ljava/lang/Object;)I
        IFGE L1
于 2013-01-13T22:00:34.357 に答える
2

それは奇妙なことですが、次のコードは私の側からコンパイルして実行します。

/**
 * @author Buhake Sindi
 * @since 14 January 2013
 *
 */
public class Test {

    public static <N extends Number & Comparable<N>, S extends N> S ensureLessThan(N threshold, S input) {
        if (input.compareTo(threshold) >= 0) {
            throw new IllegalArgumentException("Input " + input + " is not less than " + threshold);
        }
        return input;
    }

    public static void main(String[] args) {
        ensureLessThan(10, 5);
    }
}

次のJDKを使用して、Eclipse Juno(Java EE)でテストされています。

  1. JDK1.6.0_21。
  2. JDK 1.7.0_09-b05
于 2013-01-13T21:30:56.943 に答える