40

コンピューティングでは、具体化は型の明示的な表現、つまり実行時の型情報を意味するようになりました。

オラクルのチュートリアルによると、

reifiable 型は、型情報が実行時に完全に利用できる型です。これには、プリミティブ、非ジェネリック型、生の型、バインドされていないワイルドカードの呼び出しが含まれます。

非具現化不可能な型は、コンパイル時に型消去 (無制限のワイルドカードとして定義されていないジェネリック型の呼び出し) によって情報が削除された型です。

次のいずれかの場合、型は具体化可能です。

  1. プリミティブ型 ( などint) //理解
  2. パラメーター化されていないクラスまたはインターフェイスの型 ( NumberString、または などRunnable) // なぜ
  3. すべての型引数が無制限のワイルドカード ( List<?>ArrayList<?>、または などMap<?, ?>) であるパラメータ化された型 // なぜ
  4. 生の型 ( ListArrayList、または などMap) // なぜ
  5. コンポーネントの型が具体化可能な配列 ( int[]Number[]List<?>[]List[]などint[][]) // なぜ

次のいずれかの場合、型は具体化できません。

  1. 型変数 ( などT) // なぜ
  2. 実際のパラメーター ( List<Number>ArrayList<String>、または などMap<String, Integer>) を持つパラメーター化された型 // なぜ
  3. バインドされたパラメーター化された型 ( List<? extends Number>or などComparable<? super String>) // なぜ

なぜ 2,3,4,5 は具体化可能で、6,7,8 は具体化できないのでしょうか?

4

7 に答える 7

11

この 2 つの用語の意味を理解してください。

Reifiableとは、実行時に型が完全に利用可能であることを意味し、Java コンパイラが型消去のプロセスを必要としないことを意味します。

Reifiableでないということは、型が完全には利用できないため、Java コンパイラが型消去プロセスを必要とすることを意味します。

次のいずれかの場合、型は具体化可能です。

1. プリミティブ型 (int など) :

ここで、任意の int を記述または参照する場合、コンパイラは int の型を識別するための処理が必要だと思いますか? いいえ、intはintです....すべてのプリミティブ型で同じです

2. パラメーター化されていないクラスまたはインターフェイスの型 (Number、String、または Runnable など)

前の回答で、コンパイラは Number、String、または Runnable の型消去を必要としないと述べたのと同じ回答です。

3. すべての型引数が無制限のワイルドカード (List<?>、ArrayList<?>、または Map<?, ?> など) であるパラメーター化された型

すべての無制限のワイルドカードは、再定義可能な型の定義で既に言及されているため、再定義可能な型として受け入れられます。なぜそれを再定義可能な型と見なすかは、API 開発者次第です。

4. 生の型 (List、ArrayList、または Map など) ::

最初の質問と同じ答え

5. コンポーネントの型が具体化可能な配列 (int[]、Number[]、List<?>[]、List[]、int[][] など) ::

最初の質問と同じ答え

次のいずれかの場合、型は具体化できません。

6. 型変数 (T など) :

java は T の型を識別できないため、Compiler は型を識別するために型消去を必要とします。

7. 実際のパラメーターを持つパラメーター化された型 (List<Number>、ArrayList<String>、または Map<String, Integer> など) :

ここでは、すべての型はジェネリック型です。実行時コンパイラでは List as List を参照してください。

8. 境界のあるパラメーター化された型 (List<? extends Number> または Comparable<? super String> など)。

前の方と同じ回答

于 2015-11-19T20:23:25.960 に答える
7

reifiable 型は、型情報が実行時に完全に利用できる型です。これには、プリミティブ、非ジェネリック型、生の型、バインドされていないワイルドカードの呼び出しが含まれます。

非具現化不可能な型は、コンパイル時に型消去 (無制限のワイルドカードとして定義されていないジェネリック型の呼び出し) によって情報が削除された型です。具象化できない型は、実行時にすべての情報を利用できるわけではありません。具体化できない型の例は、List<String> と List<Number> です。JVM は実行時にこれらの型の違いを認識できません。ジェネリックスの制限に示されているように、具体化できない型を使用できない特定の状況があります。たとえば、式のインスタンス内で、または配列内の要素としてです。

参照

于 2013-09-17T11:44:49.363 に答える
7

あなたはグーグルに同じ質問をすることができます:

再構成可能なタイプ

ジェネリックを使用すると、多くの場合、コンパイル時の型情報が失われます。実行時に、参照についてプログラムが認識しているのは、それがある種のオブジェクトへの参照であるということだけです。実行時にすべての型情報もわかっている場合、その型は reifiable と呼ばれます。おそらくいつの日かジェネリックが再設計され、すべての型が再定義可能になるでしょう。

于 2013-09-17T11:44:15.527 に答える
0

経験に基づいた推測にすぎませんが、これを理解するための鍵は、Java が厳密に型指定された言語であり、コンパイル プロセスの一部として型参照を検証する一方で、多くの場合、型情報は実際にはロジックを実行する必要がないことを認識することだと思います。その場合、生成されたバイトコードは、オブジェクトのインスタンスで動作していることを認識している可能性がありますが、型は認識していません。厳密な型付けを使用しない言語が Java バイトコードとして生成される可能性があることを考えると、これは特に理にかなっています。したがって、オブジェクト型が削除された場合、インスタンスは具体化できなくなります。

于 2016-05-01T22:46:59.887 に答える