せかいや

いまいるここを、おもしろく http://sekai-in-the-box.appspot.com/

【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はオブジェクトではない」と本では言っていたのかもしれない。

 
と返事をしたら、
師匠はなにやら本に対して不満を言っていたけど
おおむねこういう理解でよさそう。


元記事は修正しました。