- ベストアンサー
クラスインスタンスとクラス型変数の配列
C++からシフトしてきた若輩JAVAプログラマですが、微妙に理解しきれない部分があるため、お知恵をお借りしにきました。 最初にC++のサンプルを書かせていただきます。 ----- C++ ----- class Hoge { /* 実装省略 */ } int main( void ) { Hoge *hoge = new Hoge ; Hoge *hoge = new Hoge[10] ; } --------------- これをJAVAで実装した場合、以下のようになると思います。 ----- JAVA ----- class Hoge { /* 実装省略 */ } class Test { public static void main( String[] args ) { Hoge hoge = new Hoge() ; /* 1 */ Hoge[] hoge = new Hoge[10] ; /* 2 */ } } --------------- JAVAの場合、2ではクラスのインスタンスが確保されていないことを知りました。C++ではnewの役割が「何かをメモリ上に確保する(malloc)」という意味合いであったのに対し、JAVAの場合は考え方が違うものだということでしょうか。 そうすると、 int[] a = new int[10] ; と、 Hoge[] hoge = new Hoge[10] ; のnewは、意味が違うという認識にたどり着いてしまうのですが、そうなると『妙な』気持ちがしてしまいます。そんな面倒な言語仕様では無い気もしますし。 私の考え方が間違っている可能性が高いと思いますので、教唆していただけると助かります。 よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
> JAVAの場合、2ではクラスのインスタンスが確保されていないことを知りました。 > C++ではnewの役割が「何かをメモリ上に確保する(malloc)」という意味合いであったのに対し、 > JAVAの場合は考え方が違うものだということでしょうか。 いえ~すざっつらいと。Javaでは、new Hoge[10]という式は「要素数が10で固定されているHogeの配列型」のインスタンスが生成される。ぶっちゃけ、Arrayクラスのインスタンスと思ってもらって差し支えない。参照先がnullである10個のHoge変数という事だな。なので、10個のそれぞれについてHogeクラスのインスタンスを生成して代入してあげないといけない。 intの場合はすぐ使えるじゃん! と思うかも知れないが、Javaの場合、これは値型の変数と参照型の変数という扱いで、CやC++で言う普通の変数とポインタ変数の違いと思って良い。なので、Javaでは「intの配列型」をインスタンス化すると、それは中身が参照でなくて値そのものなのですぐ使えるというわけだ。この辺は、 int i; // すぐ使える。値そのもの。 Hoge h; // nullなので、Hogeのインスタンスを代入してあげないと使えない。 と同じものだ。つまり、Hogeの配列型をインスタンス化する、とは、次の事と同じになる。 Hoge hoge0; Hoge hoge1; Hoge hoge2; ・・・ Hoge hoge9; これは全部nullやんな。結論としては、「配列をnewすると、変数が作られる」という事になる。
その他の回答 (1)
その通りです。 intやcharなどのプリミティブ型は配列をつくると中身も確保されていますが、オブジェクトは違います。 Javaの配列は単純にメモリをn個分確保するという意味ではなく、配列オブジェクトを作成するのです。 あくまでも配列オブジェクトという別のオブジェクトを作るのですから、中身は別にnewしてくださいねという考えなのだと思います。だからnew Hoge[10]の時点で、Hoge[]型のオブジェクト(Hoge型のオブジェクトが10個分ではない)がメモリ上に確保されています。 確かにちょっと奇異な感じもしますが、慣れれば面倒ではないと思います。 c++をご存知ですので、こういったJavaの癖さえ分かればすぐに慣れると思います。Javaをやっているとポインタ演算なんてややこしいものには戻れなくなりますよ。
お礼
配列オブジェクト、という概念が理解できていなかったことを知りました。 大変助かりました。 考え方を変えてみれば、JAVAの方がすっきりしているように見えてきました(笑)。理解しやすいというか。 ありがとうございます。
お礼
> Javaの場合、これは値型の変数と参照型の変数という扱いで、CやC++で言う普通の変数とポインタ変数の違いと思って良い。 なるほど!一発で氷解しました。 また、 Hoge hoge ; Hoge[] hoge ; の違いも理解できました。 ありがとうございます。これからもJAVAの道を進んでいきます(笑)。