Java は初めてなので、classとtypeの概念を混同しています。たとえば、オブジェクトはtypeまたはclass"Hello World!"
に属する必要がありますか? それとも両方? String
String
6 に答える
クラスは型です。インターフェイスは型です。プリミティブは型です。配列は型です。
したがって、すべての型は、クラス (列挙型定数を含む)、インターフェイス、プリミティブ、または配列のいずれかでもあります。
型には、プリミティブ型と参照型の 2 つの異なるカテゴリがあります。
- プリミティブ型の変数は、常に同じ型のプリミティブ値を保持します。このような値は、その変数に対する割り当て操作によってのみ変更できます。
- 参照型の変数は、常にオブジェクトへの参照の値を保持します。配列を含むすべてのオブジェクトは、 class のメソッドをサポートします
Object
。参照型には、クラス型 (列挙型を含む)、インターフェイス型、および配列型があります。
データのすべての部分には、その構造を定義する型があります。つまり、どのくらいのメモリを占有するか、どのようにレイアウトされるか、そしてさらに重要なことに、それをどのように操作できるかです。
プリミティブ型の例:
int
float
char
boolean
クラスタイプの例:
インターフェイス タイプの例:
配列タイプの例:
int[]
String[]
Integer[][][]
基本的に、変数として参照できるものにはすべて型があり、クラスは一種の型です。
詳細はこちら: http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html
「タイプ」は、より包括的なカテゴリです。Java の変数には、int や float などの 8 つの「プリミティブ」型、インターフェイス、およびクラスの 3 種類の型があります。値 (変数ではなく) は、プリミティブまたはクラスのインスタンスにすることができます。
「タイプ」は、「それがどのタイプのデータであるか」を定義します
例: "hello world" は String --> "hello world" は String 型です (String は int とは異なり事前データではないため、"hello world" は文字列クラス型であると言えます)
10 は int --> 10 は整数データ型です。
これはプログラミング用語に関する質問であり、予想通り、有効と考えられる別の回答があります。
Class<T>
リフレクション API によって公開される Java 型システムには、クラスとType
インターフェイスの2 つの型があり、前者が実装します。このシステムでは、クラス ( のインスタンスによって記述される要素Class<T>
) は、キーワードclass
orで作成された任意の型interface
、任意のプリミティブ型、任意の配列、およびvoid
です。他のすべては単なるType
.
それで、他のすべては何ですか?このコンテキストでのクラスは、オブジェクトの機能を考慮するときにランタイムが認識してアクセスできるすべてのものですが、一般に、型はコンパイラが認識するすべてのものです。これは、パラメーター化された型(型の消去により、実行時にすべてが同じクラスにマップさArrayList<String>
れることを思い出してください)、メソッドまたはクラス宣言の一部として作成されたジェネリック型パラメーター、ワイルドカード型、およびその任意の配列にすることができます。これらの型は、パラメーターの型や基本型をトラバースするときなど、型の消去が有効でないすべての場所で API メソッドによって公開されます。ArrayList<T>
型は変数や式などのコンパイル時のエンティティに関連付けられ、クラスはメモリ内オブジェクトなどの実行時のエンティティに関連付けられます。仕様15.5で使用されている言語を考えてみましょう。式と実行時チェック
式の型が参照型の場合、参照されるオブジェクトのクラス...型が参照型である式は
instanceof
、実行時の値によって参照されるオブジェクトのクラスが表現...
Practical Foundations for Programming Languagesの著者である Robert Harperは、次のように区別しています。
オブジェクトにアタッチされている可能性のあるクラスを、静的分類子である型から慎重に区別することが重要だと思います
Java ジェネリックは、この区別が関係する 1 つの例です。最初に次のスニペットを検討してください
String greeting = "Hello" + " " + "world!";
- 変数のコンパイル時の型
greeting
はString
- 式のコンパイル時の型
"Hello" + " " + "world!"
はString
Hello world!
変数によって参照されるインスタンス化されたオブジェクトの実行時クラスgreetings
はString
上記の場合、区別はあまり重要ではないように見えますが、次のスニペットで同様の推論を試してみましょう
List<String> greetings = List.of("Hello World!");
- 変数のコンパイル時の型
greetings
はList<String>
- 式のコンパイル時の型
new ArrayList("Hello World!")
はList<String>
- 変数によって参照されるインスタンス化されたオブジェクトの実行時クラス
greetings
はImmutableCollections$List1
List<String>
これで、 typeと classの間に実際に違いがあることがわかりましたImmutableCollections$List1
。コンパイラが要素の型を認識している場合、コンパイル時の型は情報が「より豊富」であることがわかりますがString
、実行時には要素の型情報は型消去のために失われます。
これは、型とクラスの違いの別のデモンストレーションです
jshell> /set feedback verbose
| Feedback mode: verbose
jshell> List.of("Hi", "Hello")
$1 ==> [Hi, Hello]
| created scratch variable $1 : List<String>
jshell> List.of(42, -11)
$2 ==> [42, -11]
| created scratch variable $2 : List<Integer>
jshell> $1.getClass() == $2.getClass()
$3 ==> true
| created scratch variable $3 : boolean
式List.of("Hi", "Hello")
との型がどのようList.of(42, -11)
に異なるかに注意してください。ただし、対応するインスタンス化されたオブジェクトのクラスは同じです。