【Java】すべてのクラスは対応するClassオブジェクトをもつ
昨日書いた記事の中でも
オブジェクトと変数の違い、
クラスはオブジェクトじゃない、
について師匠からつっこみがあったので、修正したよ。
ていうか最初のメールが
Javaの再勉強ですか 今度は吐かないようにね。 ちなみにツッコミとかあったら、また吐いちゃいます?
って。
まあ、吐いて済むなら楽な話ですよ。。
「オブジェクト」と「変数」の違い
「オブジェクト」と「変数」の違い ってやつですが、確かに違いますが それって 「ケーキ」と「お皿」は違うっていうのと同じですよね。
確かに。
こう書いた経緯は、本の中に
「メソッドの実行は変数だけができる、という訳ではありません」
とあったので。
自分なりに解釈して書いたから
文脈を共有しきれていなかったのかもしれない。
正しくはこう↓
- レシーバーが変数でないがメソッドを実行できるケース
→レシーバーがオブジェクトであり、変数に代入されていない場合
"hoge".length(); ←hogeはStringオブジェクト。
- レシーバーが変数であるがメソッドを実行できないケース
→変数が基本型を格納している場合
int a = 123; ←aの格納している123は基本型のためメソッドを持たない。
「クラスはオブジェクトじゃない」は間違い
Javaでも、クラスはオブジェクトですよ。 せかいさんが書かれている Class<?> clazz = loader.loadClass("クラス名") が、まさにクラスのオブジェクトを作ってますよ。 この clazz はメソッドの引数にも渡せるし、コレクションの要素にもできます。 第1級オブジェクトですから。 Rubyでは class C end puts C ってできるから、Javaとは違うって感じたんやろうけど Javaでも class C {} static Class<?> C = C.class; main(){ System.out.println(C); } ってできるわけで、Rubyと同じです。 逆に言うと、Rubyはこういう処理を裏でやっているだけですよ
確かに。
「Classクラスのインスタンス」はオブジェクトだ。
でも、クラスのインスタンスではなく、「Stringクラス」を
そのまま渡すのは無理ではありませんか?
String クラスをそのまま渡すってなんでしょうか? puts String という式が書けるってことを想定しているんだと思うんですが これは、「String」という名前の定数に Stringクラスオブジェクトが入っているにすぎませんよ
確かに。
Rubyのクラス宣言は結局定数にクラスオブジェクトを代入しているに過ぎない
のは前の記事で理解したところだ。
確かにRubyのクラス定義も結局は
定数へClassクラスのインスタンスを代入するだけに過ぎないから、
指摘のとおりかもしれない。
JavaだとClassクラスのインスタンスを明示的に作らないといけない
(Rubyは裏でやっている)という違いがあるだけなのか。
言い換えると、
Javaでは明示的に作らない限りClassクラスのインスタンスはできないから、
それをもって「Classはオブジェクトではない」と本では言っていたのかもしれない。
と返事をしたら、
師匠はなにやら本に対して不満を言っていたけど
おおむねこういう理解でよさそう。
元記事は修正しました。