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は、意味が違うという認識にたどり着いてしまうのですが、そうなると『妙な』気持ちがしてしまいます。そんな面倒な言語仕様では無い気もしますし。
私の考え方が間違っている可能性が高いと思いますので、教唆していただけると助かります。
よろしくお願いします。
No.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すると、変数が作られる」という事になる。
> Javaの場合、これは値型の変数と参照型の変数という扱いで、CやC++で言う普通の変数とポインタ変数の違いと思って良い。
なるほど!一発で氷解しました。
また、
Hoge hoge ;
Hoge[] hoge ;
の違いも理解できました。
ありがとうございます。これからもJAVAの道を進んでいきます(笑)。
No.1
- 回答日時:
その通りです。
intやcharなどのプリミティブ型は配列をつくると中身も確保されていますが、オブジェクトは違います。
Javaの配列は単純にメモリをn個分確保するという意味ではなく、配列オブジェクトを作成するのです。
あくまでも配列オブジェクトという別のオブジェクトを作るのですから、中身は別にnewしてくださいねという考えなのだと思います。だからnew Hoge[10]の時点で、Hoge[]型のオブジェクト(Hoge型のオブジェクトが10個分ではない)がメモリ上に確保されています。
確かにちょっと奇異な感じもしますが、慣れれば面倒ではないと思います。
c++をご存知ですので、こういったJavaの癖さえ分かればすぐに慣れると思います。Javaをやっているとポインタ演算なんてややこしいものには戻れなくなりますよ。
配列オブジェクト、という概念が理解できていなかったことを知りました。
大変助かりました。
考え方を変えてみれば、JAVAの方がすっきりしているように見えてきました(笑)。理解しやすいというか。
ありがとうございます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングのペーパーテスト 実行結果を表示せよ #include <stdio.h> int h 1 2022/07/09 15:27
- C言語・C++・C# プログラミングのペーパーテスト 実行結果がどのように表示されるか答えよ #include <stdi 1 2022/07/09 14:27
- HTML・CSS 全部のアクセスを指定したページに転送させたい 2 2022/06/28 16:33
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- XML XML同じ名前の要素を自動で集約するツール 1 2022/04/11 09:21
- Windows 10 バッチファイルの記述法とルールについてアドバイスをお願いいたします。 1 2022/04/13 10:50
- その他(プログラミング・Web制作) pythonのcondaコマンドの仕様について 2 2022/06/24 00:13
- JavaScript JavaScriptで「〇以上▲まで」の書き方 1 2022/07/20 14:44
- JavaScript javascriptで文字分割は、 split() などメソッド不要??? 4 2023/02/06 22:50
- PostgreSQL 【PostgreSQL】行の値の並びを変えるには 1 2023/03/21 16:46
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
変数名の付け方
-
オブジェクト参照がオブジェク...
-
インスタンス参照でアクセスで...
-
VB.NET getとsetの概念がわかり...
-
C# インスタンスの破棄
-
生成したインスタンスを削除す...
-
「インスタンス」の意味をわか...
-
private static という変数の修飾
-
複数の変数を宣言する時、同時...
-
メソッドの引数としてのthisの意味
-
クラスのインスタンス名をクラ...
-
エクセル(複数インスタンス)...
-
他のファイルの変数参照
-
別のフォームでインスタンスを使う
-
変数の参照でエラーが出てしま...
-
文字列を日付に変換でParseExce...
-
インスタンス生成で、○○.xxx();...
-
フィールドでのnewとコンストラ...
-
C# 自作クラスのキャストについて
-
フォームのCheck boxとOLEObjec...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
変数名の付け方
-
インスタンス参照でアクセスで...
-
private static という変数の修飾
-
VB.NET getとsetの概念がわかり...
-
次の日本語の意味を教えて下さい
-
複数の変数を宣言する時、同時...
-
C# インスタンスの破棄
-
C#において、同じインスタンス...
-
生成したインスタンスを削除す...
-
オブジェクト参照がオブジェク...
-
変数の参照でエラーが出てしま...
-
「インスタンス」の意味をわか...
-
文字列を日付に変換でParseExce...
-
フォームの存在をチェックする方法
-
エクセル(複数インスタンス)...
-
SQLを連続発行する時の正しい(?...
-
C#の構造体の開放のしかた
-
newしないインスタンス?実体化...
-
他のファイルの変数参照
-
javaのクラスの作り方、エラー...
おすすめ情報