public class CodeBlock02
{
{
System.out.println("第一代码块");
}
public CodeBlock02()
{
System.out.println("构造方法");
}
{
System.out.println("第二构造块");
}
public static void main(String[] args)
{
new CodeBlock02();
new CodeBlock02();
new CodeBlock02();
}
}
在这里, new CodeBlock02()
; 或者换成 CodeBlock02 code = new CodeBlock02();
他们是一样的吗!
먼저 몇 가지 개념을 명확히 하세요. 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 스택의 로컬 변수 테이블에 저장되는 로컬 참조를 나타내며 참조 유형 데이터를 나타냅니다.
이것을 보시면 이해가 되실 겁니다. 클래스 자체의 정보, 클래스 인스턴스 데이터, 객체를 가리키는 참조 정보는 각각 Java의 메소드 영역, 스택 영역, 힙 영역에 배치됩니다.
질문의 예:
으아아아code는 힙의 객체 인스턴스 데이터를 가리키는 지역 변수 테이블에 저장된 참조입니다. 이 객체 인스턴스 데이터는
을 통해 얻습니다.new CodeBlock02()
조금 더 구체적으로:요약하자면, 코드는 new가 생성한 인스턴스를 수신하는 데 사용하는 "원격 제어"입니다. 이는 힙 영역에서 이 개체의 특정 위치를 가리킵니다.
Java의 참조
를 이해해야 합니다.CodeBlock02 코드 = 새로운 CodeBlock02();
왼쪽에 있는 것은 CodeBlock02 유형의 변수입니다.
오른쪽에 있는 것은 CodeBlock02 유형의 객체입니다.
또한 이 변수가 동일한 유형의 서로 다른 두 개체를 차례로 가리키도록 할 수도 있습니다.
으아악이 유형의 변수가 이 유형의 하위 클래스 객체를 가리키도록 만들 수도 있습니다.
으아악다음과 같이 new로 생성된 객체에서 직접 메서드를 호출할 수도 있습니다.
으아악둘 다 선언 대상입니다. 포스터가 요구하는 것은 할당이어야 합니다
나중에 이 값을 계속 연산하지 않으면 할당 여부와 상관없이 동일하게 됩니다
new CodeBlock02() // 선언 후 값이 할당되지 않으면 이 객체에 대해 계속 작업할 방법이 없습니다.
CodeBlock02 code = new CodeBlock02() // 선언된 객체를 변수에 할당하고 후속 작업을 수행합니다. 작업을 수행할 수 있습니다
왼쪽이 해당 객체의 참조변수이고, 오른쪽이 실제로 메모리에 할당된 객체입니다.