자바 : <init>와 <clinit>의 차이점은 무엇입니까?


94

다음 텍스트를 이해할 수 없습니다 ... <clinit>빈 생성자를위한 것입니까? 두 가지 버전이 중요한 이유는 무엇입니까?

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html

2.9. Special Methods

Java 가상 머신 레벨에서 모든 생성자 (§2.12)는 특수 이름을 가진 인스턴스 초기화 메소드로 나타납니다 <init>. 이 이름은 컴파일러에서 제공합니다. 이름 <init>은 유효한 식별자가 아니기 때문에 Java 프로그래밍 언어로 작성된 프로그램에서 직접 사용할 수 없습니다. 인스턴스 초기화 메소드는 invokespecial 명령어에 의해 Java 가상 머신 내에서만 호출 될 수 있으며 초기화되지 않은 클래스 인스턴스에서만 호출 될 수 있습니다. 인스턴스 초기화 메서드는 파생 된 생성자의 액세스 권한 (§2.7.4)을 사용합니다.

클래스 또는 인터페이스에는 클래스 또는 인터페이스 초기화 메서드가 하나만 있으며 해당 메서드를 호출하여 초기화됩니다 (§2.17.4). 클래스 또는 인터페이스의 초기화 메서드는 정적이며 인수를 사용하지 않습니다. 특별한 이름이 <clinit>있습니다. 이 이름은 컴파일러에서 제공합니다. 이름 <clinit>이 유효한 식별자가 아니기 때문에 Java 프로그래밍 언어로 작성된 프로그램에서 직접 사용할 수 없습니다. 클래스 및 인터페이스 초기화 메소드는 JVM (Java Virtual Machine)에 의해 내재적으로 호출됩니다. Java 가상 머신 inw2struction에서 직접 호출되지 않지만 클래스 초기화 프로세스의 일부로 간접적으로 만 호출됩니다.

답변:


142

<init> 인스턴스의 생성자 (또는 그 중 하나)이며 비 정적 필드 초기화입니다.

<clinit> 클래스에 대한 정적 초기화 블록 및 정적 필드 초기화입니다.

class X {

   static Log log = LogFactory.getLog(); // <clinit>

   private int x = 1;   // <init>

   X(){
      // <init>
   }

   static {
      // <clinit>
   }

}


14
내 추측은 "클래스"입니다.
틸로

2
JVM이 클래스 정의를 또 다른 유형의 객체로 취급하기 때문에 흥미로운 @Thilo입니다.
Jonathan Neufeld

@JonathanNeufeld 사실이지만 몇 가지 특별한 규칙이 있다고 생각합니다. 이 메서드 (클래스 이니셜 라이저에 의해 호출 됨)는 기본으로 표시됩니다 ... grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/…
Cade Daniel

@Thilo는 "ClassLoader"를 의미 할 수도 있습니다.
Duncan Calvert


13

차이 <init><clinit>그는 인 <init>반면, 객체 인스턴스를 초기화 생성자 메소드에 사용되는 <clinit>클래스 객체 자체를 초기화하는데 사용된다. 예를 들어 static클래스 레벨 필드의 초기화 <clinit>는 클래스가로드되고 초기화 될 때 수행됩니다 .


1

추가하기 만하면 Class.forName 메서드를 사용하면 클래스 만 초기화됩니다. 따라서이 메서드 내에서 clinit 만 호출하고 forName에서 반환 된 객체에 newInstance를 사용하면 인스턴스 초기화를 위해 init를 호출합니다. 아래 코드를 사용하여 디버그에서 볼 수 있습니다.

public class ByteCodeParent
{
 public static String name="ByteCode";
 public ByteCodeParent()
{
    System.out.println("In Constructor");
}

 static
 {
     System.out.println("In Static");
 }

 {
     System.out.println("In Instance");
 }

테스트하려면

   Class<ByteCodeParent> bcp2 =(Class<ByteCodeParent>) Class.forName("ByteCodeParent");
ByteCodeParent bcp4= bcp2.newInstance();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.