2

コンパイルに失敗する次のコードがあります。

import java.util.ArrayList;
import java.util.List;

public class TypeSafetyTest {

    public static void main(String[] args) {
        TypeSafetyTest test = new TypeSafetyTest();
        test.run();
    }

    private void run() {
        Car car = new Car();
        List<String> wheelWeights = car.getWheelWeights();
    }

    private class Car {
        List<Double> wheelWeights = new ArrayList<Double>();

        public List<Double> getWheelWeights() {
            return wheelWeights;
        }

        public void setWheelWeights(List<Double> wheelWeights) {
            this.wheelWeights = wheelWeights;
        }
    }
}

次の行に「互換性のない型」エラーが表示されます。

List<String> wheelWeights = car.getWheelWeights();

ただし、行を変更すると:

private class Car {

private class Car<T> {

その後、コードは正常にコンパイルされ、コンパイル エラーが発生していた行に「未チェックの割り当て」という警告が表示されます。これはなぜですか?どちらの場合もコンパイルエラーが発生することを期待していました。

4

2 に答える 2

3

私が見る1つの問題は次のとおりです。

 public List<Double> getWheelWeights() {
            return wheelWeights;
        }

Doubletypeを返しますListが、それをに割り当てていますList<String>

変更時にコンパイル エラーが表示されない理由Car<T>は、インスタンスの作成が生の型であるためです。これは、下位互換性のために、コンパイル時に型の安全性を無視するようコンパイラに指示しているためです。

Car<Object> car = new Car<Object>();

このようにオブジェクトを変更すると、コンパイラが再びメッセージをスローすることがわかります。

詳細については、 JLS 4.8を参照してください。

JLS の例を次に示します。

    class Outer<T>{
        class Inner<S> {
            S s;
        }
    }

Outer.Inner<Double> x = null;  // illegal

部分的に生の型 (「まれな」型) として Inner にアクセスすることはできません。なぜなら、Outer 自体は生であり、Inner を含むすべての内部クラスも生であり、型引数を Inner に渡すことはできないからです。

生の型の使用は、レガシー コードの互換性への譲歩としてのみ許可されています。ジェネリックが Java プログラミング言語に導入された後に記述されたコードで生の型を使用することは、強くお勧めできません。Java プログラミング言語の将来のバージョンでは、生の型の使用が禁止される可能性があります。

Generics (Updated)を読むことをお勧めします

于 2012-12-04T21:54:55.953 に答える
3

に変更Carすると、ジェネリック クラスCar<T>になります。Carしたがって、型パラメーターを指定しなかったため、carオブジェクトには raw type が含まれるようになりました。Carまた、生の型の非静的非継承メンバーも生の型です。これは、getWheelWeights()現在生の型を返していることを意味します。また、生の型であるため、未チェックの変換が行われます。つまり、エラーではなく警告のみが表示されます。

に型引数を指定することで、これを修正できますcar。例えば

Car<Object> car = new Car();

ジェネリックの型安全性の利点が必要な場合は、生の型をまったく使用しないでください。これらは、ジェネリック前のコードの互換性修正にすぎないため、伝染性があり、生の型のチェックが不足しています。

于 2012-12-04T22:16:41.837 に答える