2017-12-30 31 views
1

クラスIは、ObjectInputStream(in)を使用してクラスVehicleのオブジェクトを読み取るコードを記述するように割り当てられました。オブジェクトはordersというArrayListに格納されます。未チェックキャストオブジェクトをArrayListにアドレス指定する方法<Vehicle>

SSCE:

// Read all orders 
Object obj = in.readObject(); 
orders = (ArrayList<Vehicle>) obj; 

はしかし、コンパイラは文句:

MacBook:Homework Brienna$ javac Orders.java -Xlint:unchecked 
Orders.java:152: warning: [unchecked] unchecked cast 
        orders = (ArrayList<Vehicle>) in.readObject(); 
                   ^
    required: ArrayList<Vehicle> 
    found: Object 
1 warning 

私はいつも私のコードの代わりに、警告を無視したり抑制を改善しよう。この場合、私は解決策を思いつきましたが、なぜそれがうまくいくのか、さらに良い解決策があるのか​​理解しようとしています。

このアップデートは、警告を停止します。私は読んでてきたものではありませんすべての要素がVehicleをしている場合(ArrayList<Vehicle>) objが例外をスローする可能性があるため、それが動作から私が理解に基づいて

// Read all orders, casting each order individually 
Object obj = in.readObject(); 
ArrayList ar = (ArrayList) obj; 
for (Object x : ar) { 
    orders.add((Vehicle) x); 
} 

。私は混乱しています - その型パラメータがVehicleとして指定されていても、非VehicleオブジェクトはArrayListに追加できますか?また、よりよい解決策がありますか? instanceofを使用していますか?

+0

...どうしてですか?なぜあなたは 'readObject'の結果から型を知らないのですか?なぜ生の型を使用していますか? (これは、生の型を扱うときのあなたの世界のようなものですが、実際にはコンパイラの警告を振ることはできません) – Makoto

+0

私は代入のためにこれをやっています。 'readObject'の予想される型は' ArrayList 'ですが、コンパイラの警告がスローされます。私が上で与えた解決策は機能します。そしてなぜそれがうまくいくのか教授の説明がわかりませんでしたので、私はより明確な説明を見つけることを望んでいます。 – briennakh

+0

ハングします。したがって、メソッドのシグネチャは 'public ArrayList readObject()'ですか?なぜ、その結果を 'Object'に保存しようとしていますか? – Makoto

答えて

2

間に違いありません。 ArrayList<?>にキャストすることは常に安全です:

Object obj = in.readObject(); 
ArrayList<?> ar = (ArrayList<?>) obj; 

orders.clear(); 
for (Object x : ar) { 
    orders.add((Vehicle) x); 
} 

あなたも、反復処理可能なように、より一般的な何かに余分な安全とキャストになりたいかもしれません:あなたがしたオブジェクトを管理している場合は

Object obj = in.readObject(); 
Iterable<?> ar = (Iterable<?>) obj; 

orders = new ArrayList<>(); 
for (Object x : ar) { 
    orders.add((Vehicle) x); 
} 

もともとはシリアル化されているので、ループを完全に回避する方法があります。コレクションの代わりに配列を使用します。配列型は常に安全なキャストです(それらがジェネリック型を持たない場合):

Object obj = in.readObject(); 
orders = new ArrayList<>(Arrays.asList((Vehicle[]) obj)); 
1

最初のコードgeneric(ArrayList)でキャストを抜粋 2番目のコードはジェネリックのないキャストを抜粋しています。 キャストは、ランタイムチェックです - Javaコンパイラは、消去を入力して、実行時に実際にあなたが接近していた List<Vehicle>List<Car>

関連する問題