このネストされたジェネリックキャストがコンパイラエラーを引き起こすのはなぜですか

マークジェロニムス:

これが以前に尋ねられた場合はすみません(ほぼ間違いありません)が、適切なキーワードが見つからないか、無関係なジェネリックの質問の山からそれを掘り下げることができません

要するに

これは機能します:

Object      a = null;
Set<Object> b = (Set<Object>)a;

では、なぜこれがコンパイラエラーになるのでしょうか。

Set<Object>      c = null;
Set<Set<Object>> d = (Set<Set<Object>>)c;

そして、なぜこの簡単な回避策が有効なのですか?

Set<Object>      e = null;
Set<?>           f = (Set<?>)e;
Set<Set<Object>> g = (Set<Set<Object>>)f;

長いバージョン:(レガシーのために保持されますが、質問には関係ありません)

Map<Number, Object>前処理されたJSONメッセージのを返すライブラリメソッドがあります手動によるディープタイプチェックの後、それをキャストしてとして返す必要がありMap<Number, Map<String, Map<String, Object>>>ます。チェックしたばかりなので無視できる、チェックされていないキャスト警告を期待しています。

ただし、コンパイラエラーが発生します。

Error:(61, 10) java: Cannot cast from java.util.Map<java.lang.Number,java.lang.Object> to java.util.Map<java.lang.Number,java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Object>>>

またはより読みやすい形式(IDEのエラーに基づく):

Inconvertible types; cannot cast 'Map<Number,Object>' to 'Map<Number,Map<String,Map<String,Object>>>'

[編集] 方法に関する質問から、理由に関する質問に変更されました

スイーパー:

ジェネリック型は実行時に消去されるため、これらのキャストを行っても実際には何も起こりません。「コンパイラはこれを許可しますか?」

ジェネリックの目的の1つは、型の安全性を確保することです。何らかの理由でに割り当てList<List<Object>>られるとList<Object>、タイプセーフが失われます。

List<List<Object>> listOfLists = new ArrayList<>();
List<Object> list = listOfLists; // suppose this is valid
list.add(new Object());
listOfLists.get(0); // what happens here?

(ここでは便宜上リストを使用しています。これはマップやセット、またはその他の一般的なタイプに簡単に適用できます)

listOfLists.get(0)Object追加したので、のインスタンスを返しますが、そうではありません!タイプList<List<Object>>だから!これが、このようにキャストできることが型の安全性を損なう理由です。

ただし、以下の2つのキャストは有効です。

List<Object>      e = null;
List<?>           f = (List<?>)e;
List<List<Object>> g = (List<List<Object>>)f;

List<?> ffは、拡張するクラスのリストですObjectが、そのクラスは何でもかまいません」を意味します。List<?>は異なることに注意してくださいList<Object>必ずしもf.add("String")?は限らないので、できませんString

最初のキャストは、ほとんどの人が(誤って)List<String>に割り当てられると信じるのと同じ理由で許可されList<Object>ます。実際、このキャストは必要ありません。A List<String> List拡張されるものですObject

2番目のキャストは?何であるかを知っていることをコンパイラに伝えることですList<Object>コンパイラ?は、チェックされていない警告を発行することにより、何間違っているかを警告します。

ある意味で、なぜIntegerto から直接キャストできないStringが、最初にIntegertoからObjectthenにキャストできるのかを尋ねるようなものですString

あなたの混乱は、間の違いの誤解が原因である可能性がありような気が<Object>して<?>この投稿は一読の価値があるかもしれません。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

保護されたC ++-Cliデストラクタがコンパイルエラーを引き起こさないのはなぜですか?

分類Dev

ジェネリック型のキャスト-括弧「()」を使用した直接キャストでコンパイルエラーが発生するのに、「as」キーワードを使用したキャストは機能するのはなぜですか?

分類Dev

ジェネリックパラメータがキャストされないのはなぜですか?

分類Dev

これらの再スローされた例外のいずれかがコンパイラエラーを引き起こすのはなぜですか?

分類Dev

ジェネリックスを含むこのKotlinコードがTypeMismatchコンパイラエラーを生成するのはなぜですか?

分類Dev

ネストされたXPATH条件付きの関数がエラーを引き起こすのはなぜですか?

分類Dev

コンパイラがジェネリッククラスコンストラクタの型を推論できないのはなぜですか?

分類Dev

コンパイラが無関係なインターフェイスタイプで呼び出されたときに、クラスタイプパラメータを持つこのジェネリックメソッドを選択するのはなぜですか?

分類Dev

これが最大コールスタックエラーを引き起こすのはなぜですか?

分類Dev

なぜC#コンパイラーはこのネストされたLINQクエリで狂ってしまうのですか?

分類Dev

クラスのostringstreamタイプのメンバーが、「暗黙的に削除されたコピーコンストラクターの呼び出し」エラーを引き起こすのはなぜですか?

分類Dev

アイテムをジェネリック型にキャストできないのはなぜですか?ジェネリック型はインターフェイスであり、アイテムがそのインターフェイスを実装していることを確認した後ですか?

分類Dev

外側のループよりもレコード数が少ないネストされたcfloopは、「配列インデックスが範囲外です」エラーを引き起こします

分類Dev

式がコンパイラエラーを引き起こすのに、ステートメントが引き起こさないのに、なぜ網羅的ではないのですか?

分類Dev

Javaでジェネリッククラスのインスタンスをスローまたはキャッチできないのはなぜですか?

分類Dev

Javaでジェネリッククラスのインスタンスをスローまたはキャッチできないのはなぜですか?

分類Dev

ジェネリッククラスコンストラクターが、要求されたインターフェイスを実装するオブジェクトの取得を拒否するのはなぜですか

分類Dev

コンポーネントタイプが内部クラスである外部パラメーター化クラスで配列を作成するのはなぜ「ジェネリック配列作成」と見なされるのですか?

分類Dev

コリジョンのネストされたイテレータループがIllegalStateExceptionを引き起こす

分類Dev

bash :()がスクリプトでエラーを引き起こしているのに、コマンドラインではエラーを引き起こしていないのはなぜですか?

分類Dev

ネストされたinitializer_listがメモリリークを引き起こすのはなぜですか

分類Dev

ArrayListのジェネリックをスーパークラスにキャストできないのはなぜですか?

分類Dev

関数から返されたクラスを使用するジェネリッククラスはエラーを引き起こします

分類Dev

ネストされたMaybeTが指数関数的な割り当てを引き起こすのはなぜですか

分類Dev

コンパイラが封印されたサブクラスをオブジェクトに変換することを提案するのはなぜですか?

分類Dev

Javaジェネリック:このネストされたテンプレートが失敗するのはなぜですか?

分類Dev

ジェネリックスを使用したこの Java インターフェース定義がコンパイラーによって受け入れられないのはなぜですか?

分類Dev

コンパイル時に、指定されたパラメータータイプのセットでジェネリックラムダを正常に呼び出すことができるかどうかを検出する方法はありますか?

分類Dev

スプライトキャラクターの更新位置がトレイルを引き起こすのはなぜですか?

Related 関連記事

  1. 1

    保護されたC ++-Cliデストラクタがコンパイルエラーを引き起こさないのはなぜですか?

  2. 2

    ジェネリック型のキャスト-括弧「()」を使用した直接キャストでコンパイルエラーが発生するのに、「as」キーワードを使用したキャストは機能するのはなぜですか?

  3. 3

    ジェネリックパラメータがキャストされないのはなぜですか?

  4. 4

    これらの再スローされた例外のいずれかがコンパイラエラーを引き起こすのはなぜですか?

  5. 5

    ジェネリックスを含むこのKotlinコードがTypeMismatchコンパイラエラーを生成するのはなぜですか?

  6. 6

    ネストされたXPATH条件付きの関数がエラーを引き起こすのはなぜですか?

  7. 7

    コンパイラがジェネリッククラスコンストラクタの型を推論できないのはなぜですか?

  8. 8

    コンパイラが無関係なインターフェイスタイプで呼び出されたときに、クラスタイプパラメータを持つこのジェネリックメソッドを選択するのはなぜですか?

  9. 9

    これが最大コールスタックエラーを引き起こすのはなぜですか?

  10. 10

    なぜC#コンパイラーはこのネストされたLINQクエリで狂ってしまうのですか?

  11. 11

    クラスのostringstreamタイプのメンバーが、「暗黙的に削除されたコピーコンストラクターの呼び出し」エラーを引き起こすのはなぜですか?

  12. 12

    アイテムをジェネリック型にキャストできないのはなぜですか?ジェネリック型はインターフェイスであり、アイテムがそのインターフェイスを実装していることを確認した後ですか?

  13. 13

    外側のループよりもレコード数が少ないネストされたcfloopは、「配列インデックスが範囲外です」エラーを引き起こします

  14. 14

    式がコンパイラエラーを引き起こすのに、ステートメントが引き起こさないのに、なぜ網羅的ではないのですか?

  15. 15

    Javaでジェネリッククラスのインスタンスをスローまたはキャッチできないのはなぜですか?

  16. 16

    Javaでジェネリッククラスのインスタンスをスローまたはキャッチできないのはなぜですか?

  17. 17

    ジェネリッククラスコンストラクターが、要求されたインターフェイスを実装するオブジェクトの取得を拒否するのはなぜですか

  18. 18

    コンポーネントタイプが内部クラスである外部パラメーター化クラスで配列を作成するのはなぜ「ジェネリック配列作成」と見なされるのですか?

  19. 19

    コリジョンのネストされたイテレータループがIllegalStateExceptionを引き起こす

  20. 20

    bash :()がスクリプトでエラーを引き起こしているのに、コマンドラインではエラーを引き起こしていないのはなぜですか?

  21. 21

    ネストされたinitializer_listがメモリリークを引き起こすのはなぜですか

  22. 22

    ArrayListのジェネリックをスーパークラスにキャストできないのはなぜですか?

  23. 23

    関数から返されたクラスを使用するジェネリッククラスはエラーを引き起こします

  24. 24

    ネストされたMaybeTが指数関数的な割り当てを引き起こすのはなぜですか

  25. 25

    コンパイラが封印されたサブクラスをオブジェクトに変換することを提案するのはなぜですか?

  26. 26

    Javaジェネリック:このネストされたテンプレートが失敗するのはなぜですか?

  27. 27

    ジェネリックスを使用したこの Java インターフェース定義がコンパイラーによって受け入れられないのはなぜですか?

  28. 28

    コンパイル時に、指定されたパラメータータイプのセットでジェネリックラムダを正常に呼び出すことができるかどうかを検出する方法はありますか?

  29. 29

    スプライトキャラクターの更新位置がトレイルを引き起こすのはなぜですか?

ホットタグ

アーカイブ