java在类的内部创建本类的对象是怎么做到的?不理解啊?
ringa_lee
ringa_lee 2017-04-18 10:51:14
0
8
493

ringa_lee
ringa_lee

ringa_lee

全員に返信(8)
黄舟

まず、いくつかの概念を明確にしましょう。Java コードは jvm で実行され、jvm のメモリ領域はいくつかのモジュールに分割されます。

  • プログラム カウンター レジスタ: プログラム カウンターは、現在のスレッドによって実行されたバイトコードの行を示すために使用される比較的小さなメモリ領域です。これは、現在のスレッドの行番号インジケーターとして理解できます。バイトコード インタプリタが動作しているときは、このカウンタの値を変更することによってステートメント命令をフェッチします。

  • 仮想マシン スタック (JVM スタック):

    スレッドの各メソッドが実行されると、スタック フレーム (Statck フレーム) が作成され、ローカル変数テーブル、オペレーション ステーション、ダイナミック リンク、メソッド Exit などが格納されます。 . メソッドが呼び出されると、スタック フレームが JVM スタックにプッシュされ、メソッドの実行が完了すると、スタック フレームがスタックからポップアウトされます。

  • ネイティブ メソッド スタック:

    ネイティブ メソッド スタックは、機能、動作メカニズム、例外タイプなどの点で仮想マシン スタックと同じです。唯一の違いは、仮想マシン スタックは Java メソッドを実行するのに対し、ネイティブ メソッドはスタックは、ネイティブ メソッドの実行に使用されます。多くの仮想マシン (Sun の JDK デフォルト HotSpot 仮想マシンなど) では、ネイティブ メソッド スタックと仮想マシン スタックが一緒に使用されます。

  • ヒープ:

    ヒープ領域は、Java GCメカニズムを理解する上で最も重要な領域です。ヒープ領域は、JVM によって管理される最大のメモリ領域であり、Java GC メカニズムによって管理されるメイン メモリ領域でもあり、仮想マシンの起動時に作成されます。ヒープ領域は、オブジェクト インスタンスを格納するために存在します。原則として、すべてのオブジェクトはヒープ領域にメモリが割り当てられます (ただし、最新のテクノロジーでは、これはそれほど絶対的なものではなく、一部のオブジェクトはスタックに直接割り当てられます)。

  • メソッド領域:

    (永続世代とも呼ばれます)、メソッド領域は各スレッドによって共有される領域であり、仮想マシンによってロードされたクラス情報 (つまり、必要な情報) を格納するために使用されます。クラスのロード時にロードされます(バージョン、フィールド、メソッド、インターフェイス、その他の情報を含む)、最終定数、静的変数、オンザフライでコンパイラによってコンパイルされたコードなど。

  • ダイレクトメモリ:

    ダイレクトメモリはJVMによって管理されるメモリではありません。たとえば、4Gのメモリがあり、JVMが1Gを占有している場合、残りの3Gはダイレクトメモリであると理解できます。 JDKにはチャネルとバッファに基づいたメモリ割り当て方式があり、C言語で実装されたネイティブ関数ライブラリはダイレクトメモリに割り当てられ、JVMヒープに格納されたDirectByteBufferによって参照されます。ダイレクトメモリは本機のメモリによって制限されるため、OutOfMemoryError例外が発生する場合もあります。

  • これらの基本概念を理解した上で、質問者が疑問に思っている部分を見てみましょう。実際、質問者が疑問に思っているのは、オブジェクト参照が Java でどのように実装されるかということです。クラスを定義するときに独自の参照を定義できるのはなぜですか?同時にこの参照をインスタンス化すると、無限循環参照が発生するのではありませんか?

心配しないで、まず Java で参照がどのように実装されるかを分析しましょう:

Java 参照アクセスには、JVM スタック、ヒープ、メソッド領域の 3 つのメモリ領域が関係します。

最も単純なローカル変数参照: Object obj = new Object() を例として挙げます:

  • Object obj は、JVM スタックのローカル変数テーブルに格納され、参照型データを表すローカル参照を表します。

  • new Object() はインスタンス オブジェクト データとしてヒープに保存されます。
  • オブジェクトクラスの型情報(インターフェース、メソッド、フィールド、オブジェクトタイプなど)のアドレスもヒープに記録され、そのアドレスで実行されたデータはメソッド領域に格納されます。

  • 具体的な実装方法はたくさんありますが、handleもその一つで、関係は図のとおりです。

これを見れば分かるはずです。クラス自身の情報、クラスのインスタンスデータ、オブジェクトを指す参照情報はそれぞれjavaのメソッド領域、スタック領域、ヒープ領域に配置されます。
件名の例では、Java の読み込み順序は次のようになります:

jvm は最初にメソッド領域にクラス定義をロードします (ただし、この時点ではこのクラスはインスタンス化されていません)

  1. は静的変数であるため、JVMが初めてメソッド領域定義を読み取るときに、この変数もメソッド領域にロードされます。

  2. 同時に、これは、この変数のロード中に、このクラスのインスタンスもヒープ領域でインスタンス化されることも意味します。

    public static final Direction FRONT = new Direction();

  3. ここで重要な点に注意してください。FRONT 変数は静的変数であり、ロードされたクラス定義は 1 回だけロードされるため、この静的変数は 1 回しかロードできません。非静的変数のような循環参照のインスタンス化が繰り返されてもスタック オーバーフローが発生することはありません。
いいねを押す +0
大家讲道理

Rの回答を読むことをお勧めします

クラスとオブジェクトどちらが先ですか?
https://www.zhihu.com/questio...

いいねを押す +0
Peter_Zhu

クラス内で独自のオブジェクトを作成できないのはなぜですか? あなたの理解を教えてください。
static を追加した後、これらの変数はクラスの属性になり、一度だけ作成されます。

いいねを押す +0
伊谢尔伦

自分自身を作成できない場合、他のクラスも作成できません。この場合、このクラスをどのようにインスタンス化するか...

いいねを押す +0
大家讲道理

デザインパターン: シングルトンパターン

いいねを押す +0
PHPzhong

本質は、Java のオブジェクト指向プログラミングに対する理解の欠如です。 23種類のデザインパターンを見れば分かるかもしれません

いいねを押す +0
伊谢尔伦
  1. コンストラクターもメソッドです。

  2. private アクセス権を持つメソッドはプライベートであり、このクラスにのみ表示されます。 private 访问权限的方法表示私有的,只有本类可见。

所以,本类可以调用具有 private

🎜したがって、このクラスは、private アクセス権でコンストラクターを呼び出して、オブジェクトをインスタンス化できます。 🎜
いいねを押す +0
巴扎黑

内部クラスを使用する理由: 各内部クラスは (インターフェース) 実装を独立して継承できるため、外部クラスが (インターフェース) 実装を継承したかどうかに関係なく、内部クラスには影響しません。実際、内部クラスは効果的に「多重継承」を実装します。つまり、内部クラスは複数の非インターフェイス型の継承を許可します。

内部クラスが外部クラスのすべてのメンバーに自動的にアクセスできることはわかっていますが、これはどのように行われるのでしょうか?外部クラス オブジェクトが内部クラス オブジェクトを作成する場合、内部クラス オブジェクトはその外部クラス オブジェクトへの参照を秘密裏にキャプチャする必要があります。次に、外部クラスのメンバーにアクセスするときに、その参照を使用して外部クラスのメンバーを選択します。もちろん、これらの詳細はコンパイラーによって処理され、ここでの内部クラスは非静的です。
クラスが独自のクラスオブジェクトを作成できない場合、そのクラスは何の役に立つのでしょうか?あ、はははは、冗談です

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!