>  Q&A  >  본문

java在类的内部创建本类的对象是怎么做到的?不理解啊?

ringa_leeringa_lee2743일 전501

모든 응답(8)나는 대답할 것이다

  • 黄舟

    黄舟2017-04-18 10:53:14

    먼저 몇 가지 개념을 명확히 하세요. Java 코드는 jvm에서 실행되며, jvm의 메모리 영역은 여러 모듈로 나뉩니다.

    • 프로그램 카운터 레지스터: 프로그램 카운터는 현재 스레드가 실행한 바이트코드의 어느 라인이 실행되었는지 나타내는 데 사용되는 비교적 작은 메모리 영역입니다. 현재 스레드에 대한 표시기입니다. 바이트코드 인터프리터가 작동 중일 때 이 카운터의 값을 변경하여 명령문 명령을 가져옵니다.

    • JVM 스택: 스레드의 각 메소드가 실행되면 스택 프레임(Statck Frame)이 생성되고 로컬 변수 테이블이 스택 프레임, 작업 스테이션에 저장됩니다. , 동적 링크, 메소드 종료 등. 메소드가 호출되면 스택 프레임이 JVM 스택으로 푸시됩니다. 메소드 실행이 완료되면 스택 프레임이 스택에서 팝됩니다.

    • 네이티브 메소드 스택: 네이티브 메소드 스택은 기능, 작동 메커니즘, 예외 유형 등의 측면에서 가상 머신 스택과 동일합니다. 유일한 차이점은 가상 머신 스택입니다. Java 메서드 실행은 로컬 메서드 스택이 기본 메서드를 실행하는 데 사용되는 반면, 많은 가상 머신(예: Sun의 JDK 기본 HotSpot 가상 머신)에서는 로컬 메서드 스택과 가상 머신 스택이 함께 사용됩니다.

    • 힙: 힙 영역은 말할 것도 없이 Java GC 메커니즘을 이해하는 데 가장 중요한 영역입니다. 힙 영역은 JVM이 관리하는 가장 큰 메모리 부분이며 Java GC 메커니즘이 관리하는 주요 메모리 영역이기도 합니다. 힙 영역은 모든 스레드가 공유하며 가상 머신이 시작될 때 생성됩니다. 힙 영역은 객체 인스턴스를 저장하기 위해 존재합니다. 원칙적으로 모든 객체에는 힙 영역에 메모리가 할당됩니다(그러나 현대 기술에서는 이것이 절대적이지 않으며 일부 객체는 스택에 직접 할당됩니다).

    • 메서드 영역: (영구 생성이라고도 함) 메서드 영역은 각 스레드가 공유하는 영역으로 가상 머신에서 로드한 클래스 정보를 저장하는 데 사용됩니다( 즉, 버전, 필드, 메서드, 인터페이스 및 기타 정보를 포함하여 클래스를 로드할 때 로드해야 하는 정보, 최종 상수, 정적 변수, 컴파일러에서 즉시 컴파일된 코드 등입니다.

    • 직접 메모리: 직접 메모리는 JVM에서 관리하는 메모리가 아닙니다. 다이렉트 메모리는 JVM이 아닌 머신 메모리라고 이해하면 됩니다. 1G를 차지하고 나머지 3G는 다이렉트 메모리이다. JDK에는 C언어로 구현된 네이티브 함수 라이브러리를 다이렉트 메모리에 할당하고 참조하기 위해 JVM 힙에 저장한다. . 직접 메모리는 이 컴퓨터의 메모리에 의해 제한되므로 OutOfMemoryError 예외가 발생할 수도 있습니다.

    이러한 기본 개념을 이해한 후, 질문자가 의심하는 부분을 살펴보겠습니다. 실제로 질문자가 궁금해하는 것은 Java에서 객체 참조가 어떻게 구현되는지입니다. 클래스를 정의하면서 자신만의 참조를 정의할 수 있는 이유는 무엇입니까? 동시에 이 참조를 인스턴스화하면 무한 순환 참조가 발생하지 않을까요?

    걱정하지 마세요. 먼저 Java에서 참조가 어떻게 구현되는지 분석해 보겠습니다.

    Java 참조 액세스에는 JVM 스택, 힙, 메서드 영역이라는 세 가지 메모리 영역이 포함됩니다.

    가장 간단한 지역 변수 참조: Object obj = new Object()를 예로 들어보겠습니다.

    • 객체 obj는 JVM 스택의 로컬 변수 테이블에 저장되는 로컬 참조를 나타내며 참조 유형 데이터를 나타냅니다.

    • new Object()는 인스턴스 객체 데이터로 힙에 저장됩니다.
    • 객체 클래스의 유형 정보(인터페이스, 메소드, 필드, 객체 유형 등)의 주소도 힙에 기록되고, 이 주소에서 실행되는 데이터는 메소드 영역에 저장됩니다.
    • 구체적인 구현 방법은 여러 가지가 있는데, 핸들이 그 중 하나이며, 관계는 그림과 같습니다.


    이것을 보시면 이해가 되실 겁니다. 클래스 자체의 정보, 클래스 인스턴스 데이터, 객체를 가리키는 참조 정보는 각각 Java의 메소드 영역, 스택 영역, 힙 영역에 배치됩니다.

    주제의 예시에서 자바 로딩 순서는 다음과 같습니다.

      jvm은 먼저 메소드 영역에 클래스 정의를 로드합니다(그러나 이 시점에서는 클래스가 인스턴스화되지 않습니다)
    1. 은 정적 변수이므로 jvm이 처음으로 메서드 영역 정의를 읽을 때 이 변수도 메서드 영역에 로드됩니다.

      public static final Direction FRONT = new Direction();

    2. 동시에 이는 이 변수를 로드하는 동안 이 클래스의 인스턴스도 힙 영역에서 인스턴스화된다는 의미이기도 합니다.
    3. 여기서 핵심 사항에 주의하세요. FRONT 변수는 정적 변수이고, 로드된 클래스 정의는 한 번만 로드되므로 이 정적 변수는 한 번만 로드할 수 있습니다. 비정적 변수와 같은 순환 참조의 반복된 인스턴스화로 인해 스택 오버플로가 발생하지 않습니다.

    회신하다
    0
  • 大家讲道理

    大家讲道理2017-04-18 10:53:14

    R의 답변을 읽어보시길 권합니다

    클래스와 객체 중 어느 것이 먼저인가요?
    https://www.zhihu.com/questio...

    회신하다
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:53:14

    이해하신 내용을 말씀해 주세요. 수업 중에 자신만의 개체를 만들 수 없는 이유는 무엇인가요?
    정적을 추가한 후 이러한 변수는 클래스의 속성이 되며 한 번만 생성됩니다.

    회신하다
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:53:14

    직접 만들 수 없다면 다른 클래스도 만들 수 없습니다. 이 경우 이 클래스를 인스턴스화하는 방법은...

    회신하다
    0
  • 大家讲道理

    大家讲道理2017-04-18 10:53:14

    디자인 패턴: 싱글턴 패턴

    회신하다
    0
  • PHPz

    PHPz2017-04-18 10:53:14

    핵심은 Java의 객체지향 프로그래밍에 대한 이해 부족입니다. 23가지 디자인 패턴을 보시면 이해가 되실 겁니다

    회신하다
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:53:14

    1. 생성자도 메소드입니다.

    2. private 액세스 권한이 있는 메서드는 비공개이며 이 클래스에만 표시됩니다.

    따라서 이 클래스는 private 액세스 권한이 있는 생성자를 호출하여 객체를 인스턴스화할 수 있습니다.

    회신하다
    0
  • 巴扎黑

    巴扎黑2017-04-18 10:53:14

    내부 클래스를 사용하는 이유: 각 내부 클래스는 (인터페이스) 구현에서 독립적으로 상속할 수 있으므로 외부 클래스가 (인터페이스) 구현을 상속했는지 여부는 내부 클래스에 영향을 미치지 않습니다. 실제로 내부 클래스는 "다중 상속"을 효과적으로 구현합니다. 즉, 내부 클래스는 인터페이스가 아닌 여러 유형의 상속을 허용합니다.

    내부 클래스가 외부 클래스의 모든 멤버에 자동으로 액세스할 수 있다는 것을 알고 있는데, 이를 어떻게 수행합니까? 외부 클래스 개체가 내부 클래스 개체를 생성할 때 내부 클래스 개체는 해당 외부 클래스 개체에 대한 참조를 비밀리에 캡처해야 합니다. 그런 다음 외부 클래스의 멤버에 액세스할 때 해당 참조를 사용하여 외부 클래스의 멤버를 선택합니다. 물론 이러한 세부 사항은 컴파일러에 의해 처리되며 여기의 내부 클래스는 비정적입니다.
    클래스가 자체 클래스 객체를 생성할 수 없다면 클래스가 무슨 소용이 있나요? 아, 하하하하, 농담이에요

    회신하다
    0
  • 취소회신하다