1

私は次のコードを持っています、

class Foo<K> {

    public <T> T createK() {
        return null;
    }

    public void foo() throws ClassNotFoundException {
        K k = (1==1)?null:createK();
    }
}

ただし、コンパイルされませんでした。条件演算子のある行で、次のコンパイル エラー (Oracle Java 7) が発生しました。

型の不一致: Object から K に変換できません

foo()メソッドを次のように書き換えると、

public void foo() throws ClassNotFoundException {
    K k = null;
    if (1==1)
        k = null;
    else
        k = createK();
}

その後、正常にコンパイルされます。これはどのように発生し、どうすれば解決できますか?

4

5 に答える 5

6

条件演算子は条件演算子とまったく同じではありませんif-elseが、これは別の問題です。

これは、条件演算子を使用したジェネリック型パラメーターの型推論に関する既知のバグであり、期待どおりに動作しません。

解決策は、明示的な型引数を提供することです。

K k1 = (1==1) ? null : this.<K>createK(); 

...これは機能しますが、コンパイラの警告が表示されます-デッドコード(もちろん、1 == 1一部による)。this明示的な型引数でメソッドを呼び出すために明示的に使用する必要があることに注意してください。するだけではうまく<K>createK()いきません。

メソッド呼び出しで明示的な型引数を追加する -this.<K>createK();強制的に型Tを と推論しますKが、それ以外の場合は と推論しObjectます。


ただし、あなたの疑問は実際には型推論に関連していると思われます。問題がそれであることが判明したのは単なる偶然です。それでも、さまざまな状況で条件演算子がどのように機能するか、およびその結果のタイプについて理解するには、JLS §15.25 - 条件演算子への訪問をスケジュールできます。

于 2013-10-10T20:07:39.803 に答える
4

いいえ、三項(つまり? :) は とはまったく異なる獣ですif ... then ... else

三項は演算子であり、2 つの選択肢は同じ型に評価される式でなければなりません。

if ... then ... else便利なプログラミング構造です。間のビットは式ではなくステートメントです。

実際、三項構造全体if ... then ... elseが式ですが、それ自体がステートメントです。(三項に値を代入できます。たとえば、意味foo = ... ? ... : ...foo = if ... then ... elseないため、構文的に無効です。)

于 2013-10-10T20:02:15.130 に答える
1

条件式の両側の型が一致する必要があるため、コードはコンパイルされません。if ステートメントにはそのような要件はありません。実際、同じ変数を割り当てることは言うまでもなく、2 つの部分が互いに関連している必要はありません。

キャストを追加すると、条件が修正されます ( demo on ideone ):

K k = (1==1)?null:(K)createK();
于 2013-10-10T20:04:50.500 に答える