2013-03-15 9 views
6

私はこれに対する答えを探していましたが、無駄です。私の疑問は、なぜジェネリック医薬品で倒産することができないのかということです。私は仕事というクラスを持っているとモデルJavaのListクラスを使用してダウンキャストできませんでした

// error: Cannot cast from List<Model> to List<Job> 
List<Job> jobs = (List<Job>) jobMapper.fetchAll(); 

jobMapper.fetchAll()が返すのリストを生成

Job extends Model 

は今、私は再利用可能なコードからのジョブのコレクションを取得モデル

と呼ばれるクラスを拡張しますその内部の各モデルがJobオブジェクトであるList。

私は私が行うことができますので、これはうまくいくと仮定:シンプルなダウンキャストである

EditText mUsername = (EditText) findViewById(R.id.editUserName); 

+0

可能重複http://stackoverflow.com/questions/933447/how-do-you-cast-a- – artbristol

+0

ジョブはModelのサブクラスであり、Job []はModel []のサブクラスですが、リストはリストのサブクラスではありません。 – StarPinkER

+0

@JermaineXu: "サブタイプ"はここで "サブクラス"より正確です。 'List 'は実際にはクラスではなく型です。 (そして、あなたは 'ジョブ[]はクラスでもないと主張することができます)。 –

答えて

10

Javaはこれを許可していないため、これを行うことはできません。あなたは、トリックを行う必要がありRead this.

List<Job> jobs = (List<Job>) ((List<?>)jobMapper.fetchAll()); 
+0

素晴らしい!それがトリックでした。私はチェックされていないキャストの警告を取得している間、私はキャストされている値のかなり確信しているので、私はそれで生きることができます。ご協力いただきありがとうございます。それをたくさんありがとう! – Strategist

+2

ところで、それはかなり悪い考えです。警告を非表示にして、ジェネリック型の情報(およびジェネリックスから得られるすべての保証)をこのリストから効果的に削除します。 –

+0

@ジョアヒムはこれを行う良い方法がありますか?あなたは答えを投稿してください。ありがとう – Strategist

2

あなたは、次の操作を行うことができます

List<Job> jobs = (List) (jobMapper.fetchAll()); 

(そして、あなたはそれがあなたのケースに安全だと確信している場合に警告を抑制する)

コンパイラは、リスト<ジョブ>リストとリスト<モデル>が同じリストを指していれば、後者にモデルインスタンスを追加してリストを作成することができるので、試したキャストを許可していません< Job>型の安全性を損なうModelアイテムがあります。

したがって、この種のトリックを許可するときは注意してください。後で、ClassCastExceptionが発生することを想定していない形式で返される可能性があります。一覧<仕事>リスト<モデルではありません>:ジ​​ョブモデルであり、ジョブ[] []は、それがコレクションのために真実ではないモデルである一方であることに注意してください:あなたの最後の質問について

。これはちょっと驚くべきことですが、上記の説明からわかります。これは警告/エラーなしでこのキャストを可能にするために型の安全性を損なうでしょう。

+0

ありがとうございましたこれはまた、もちろん警告で動作します。 – Strategist

+0

2番目のコメントは申し訳ありません。間違ったボックスに投稿されました – Strategist

0
List<Job> jobs = jobMapper.fetchAll(); 

間違っても、明らかにジョブのリストではありません。

使用

List<? super Job> jobs = jobMapper.fetchAll(); 

代わりに。

+0

これは、オブジェクトとしてジョブを繰り返し実行し、ジョブにキャストできます。 –

+0

これは明示的なリストobジョブではないためです。 :D –

+0

申し訳ありませんが、これは私のためには機能しません。行は警告のみを出します。配列の配列ArrayAdapter でこの変数を使用しているため、jobs変数を使用できなくなりました。このコレクションをアダプタとして追加できなくなりました。リスト Strategist

0

実行時にエラーが発生する可能性があるため、許可されていません。リストにすでにクラスJob以外のオブジェクトが含まれていた場合はどうなりますか?

次のいずれかのはず:List<Job>を返すために

  1. 変更jobMapper.fetchAll()

  2. リストの代わりにオブジェクトをキャストします。Job job = (Job) jobs.get(0)

[あなたはJavaである型から別の型のオブジェクトの一覧をキャストするにはどうすればよい?](の
+0

同様の方法でfindViewById()の例のEditTextへのキャストはRuntimeExceptionsにつながる可能性がありますが、それでも可能です。 – baske

+0

fetchAllは再利用している基本クラスのメソッドなので、jobMapper.fetchAll()をList に戻すことはできません。私はUserMapper.fetchAll()を実行してUserオブジェクトを返します(User extends Model)。 – Strategist

+0

@baske:EditTextへのキャストはオブジェクトをキャストします。そのようなキャストを行うときはClassCastExceptionを期待する必要があります。しかし、ジェネリックコンテナからオブジェクトを取得するときは、返された要素をキャストしないので、コレクションをキャストしてすべての警告を無視しない限り、ClassCastExceptionを取得することはありません(LeonidasによるソリューションへのJoachim Sauerのコメントを参照)。 – Axel

関連する問題