자바 정적 초기 화 블록 분석
머리말
자바 응용 프로그램 을 개발 할 때 많은 장면 에서 정적 초기 화 블록 (Static Initialization Blocks) 을 사용 해 야 합 니 다.본 고 는 그것 에 대해 간략하게 분석 할 것 이다.
소개 하 다.
정적 초기 화 블록 은 static 키 워드 를 표시 하 는 괄호 에 닫 힌 일반 코드 블록 입 니 다.정적 초기 화 블록 은 클래스 가 초기 화 될 때 실 행 됩 니 다. 클래스 의 전체 수명 주기 에서 한 번 만 실 행 됩 니 다.따라서 클래스 의 정적 도 메 인 을 초기 화하 고 클래스 가 구 조 될 때 우선 실행 해 야 할 코드 를 실행 하 는 데 사 용 됩 니 다.
활용 단어 참조
JDK 소스 코드 중 몇 가지 유형 은 다음 과 같은 코드 를 사 용 했 습 니 다.
private static native void registerNatives();
static {
registerNatives();
}
클래스 가 구 성 될 때 바로 registernatives 방법 으로 로 컬 함 수 를 등록 할 수 있 도록 정적 초기 화 블록 을 사용 합 니 다.
정적 초기 화 블록 은 상수 도구 클래스 에 도 사용 할 수 있 습 니 다. 설정 파일 에서 정적 속성 을 초기 화 할 수 있 습 니 다.
public class Constants {
private static final String PFILE = "constants";
private static String property = "";
private Constants() {
}
static {
copyProperties(PFILE);
}
private static void copyProperties(String fileName) {
ResourceBundle rb = ResourceBundle.getBundle(fileName);
Map<String, Object> map = new HashMap<String, Object>();
Constants constants = new Constants();
Enumeration<String> enums = rb.getKeys();
while (enums.hasMoreElements()) {
String key = enums.nextElement();
map.put(key, rb.getString(key).trim());
}
try {
BeanUtils.copyProperties(constants, map);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
public static String getProperty() {
return property;
}
public void setProperty(String property) {
Constants.property = property;
}
}
실행 시기
정적 초기 화 블록 은 클래스 가 초기 화 될 때 실 행 됩 니 다. 구체 적 으로 다른 코드 블록 과 의 실행 순 서 는 무엇 입 니까?
예제 코드:
public class Demo {
static {
System.out.println("Static initialization block.");
}
{
System.out.println("Initialization block.");
}
public Demo() {
System.out.println("Constructor.");
}
public static void staticMethod() {
System.out.println("Static method.");
}
public void dynamicMethod() {
System.out.println("Dynamic method.");
}
}
public class Main {
public static void main(String args[]) throws ClassNotFoundException {
System.out.println("Main method.");
Class.forName("Demo");
Class.forName("Demo");
}
}
실행 결과:
Main method.
Static initialization block.
클래스. forName 방법 으로 클래스 를 불 러 올 때 클래스 가 초기 화 되 고 정적 초기 화 블록 이 실행 되 며 한 번 만 실 행 됩 니 다.
비 정적 방법
main 방법 수정:
public static void main(String args[]) {
System.out.println("Main method.");
new Demo().dynamicMethod();
}
실행 결과:
Main method.
Static initialization block.
Initialization block.
Constructor.
Dynamic method.
실행 순 서 는 정적 초기 화 블록 - > 초기 화 블록 - > 구조 방법 - > 인 스 턴 스 방법 입 니 다.
정적 방법
main 방법 수정:
public static void main(String args[]) {
System.out.println("Main method.");
Demo.staticMethod();
}
실행 결과:
Main method.
Static initialization block.
Static method.
정적 초기 화 블록 도 정적 방법 보다 우선 합 니 다.
main 방법
상기 main 방법 을 데모 류 에 복사 하여 실행 하면?
실행 결과:
Static initialization block.
Main method.
Static method.
정적 초기 화 블록 역시 정적 방법 보다 우선 하고 main 방법 보다 우선 합 니 다.
클래스 에서 main 방법 을 프로그램의 입구 로 정의 한 경우 클래스 가 직접 인용 되 기 때문에 클래스 의 초기 화 를 촉발 할 수 있 습 니 다.
Core Java 에서 언급 한 바 와 같이 main 방법 이 없 는 Hello, World 프로그램 을 만 들 수 있 습 니 다.
public class Hello {
static {
System.out.println("Hello, World!");
}
}
자바 Hello 보기 결과 실행:
Hello, World!
Exception in thread "main" java.lang.NoSuchMethodError: main
System. exit (0) 를 추가 하여 이상 한 정 보 를 출력 하지 않도록 할 수 있 습 니 다.
그러나 이 프로그램 은 JDK 1.7 에서 직접 오 류 를 보고 합 니 다.
: Hello , :
public static void main(String[] args)
정적 필드
정적 초기 화 블록 과 정적 변수 간 의 실행 순 서 는 무엇 입 니까?
예제 코드:
public class Demo {
static {
x = 200;
}
public static int x = 100;
public static void main(String args[]) {
System.out.println("x = " + Demo.x);
}
}
실행 결과:
x = 100
정적 변수 x 의 값 이 바 뀌 지 않 았 습 니 다. 그러면 정적 초기 화 블록 안의 코드 가 실행 되 었 습 니까?
정적 초기 화 블록 내 할당 문 앞 뒤 출력 x 의 값:
static {
System.out.println("x1 = " + Demo.x);
x = 2;
System.out.println("x2 = " + Demo.x);
}
실행 결과:
x1 = 0
x2 = 200
x = 100
상기 코드 가 정적 초기 화 블록 에서 의 할당 문 구 는 변수 정의 에서 의 할당 문 구 를 먼저 실행 하 는 것 을 설명 합 니 다. 그런데 왜 이 정적 변 수 를 방문 할 수 있 습 니까?
인쇄 문 구 를 제거 한 후 어 셈 블 리 코드 보기:
Compiled from "Demo.java"
public class Demo {
public static int x;
static {};
Code:
0: sipush 200
3: putstatic #10 // Field x:I
6: bipush 100
8: putstatic #10 // Field x:I
11: return
public Demo();
Code:
0: aload_0
1: invokespecial #15 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.lang.ClassNotFoundException;
Code:
0: return
}
정적 변수의 정의 문 구 는 두 부분 으로 나 뉘 어 먼저 정 의 를 한 다음 에 값 을 부여 한 것 을 볼 수 있다.정적 변수 가 정 의 될 때 할당 작업 은 정적 초기 화 블록 의 할당 작업 뒤에 놓 여 있 습 니 다.
실제로 자바 c 컴 파일 을 사용 하여 바이트 코드 를 생 성 할 때 컴 파일 러 는 클래스 구조 기 < clinit > 방법 을 문법 트 리 에 추가 합 니 다. 클래스 초기 화 시 JVM 은 정적 영역 과 정적 초기 화 블록 의 논 리 를 모두 봉인 합 니 다.
코드 수정:
public class Demo {
public static int x = 100;
static {
x = 200;
}
public static void main(String args[]) {
System.out.println("x = " + Demo.x);
}
}
실행 결과:
x = 200
따라서 헷 갈 리 지 않도록 정적 영역 에 값 을 부여 할 때 정적 방법 을 사용 하 는 것 이 좋 습 니 다.
public class Demo {
public static int x = initX();
public static int initX() {
return 200;
}
public static void main(String args[]) {
System.out.println("x = " + Demo.x);
}
}
위 에서 언급 한 바 와 같이 정적 필드 와 정적 초기 화 블록 은 순서대로 실 행 됩 니 다. 그러면 다음 코드 의 실행 결 과 는 무엇 입 니까?
public class Demo {
public static Demo demo = new Demo();
static {
System.out.println("Static initialization block.");
}
{
System.out.println("Initialization block.");
}
public Demo() {
System.out.println("Constructor.");
}
public static void main(String args[]) {
System.out.println("Main method.");
}
}
실행 결과:
Initialization block.
Constructor.
Static initialization block.
Main method.
이런 특수 한 상황 에서 정적 초기 화 블록 은 구조 방법 보다 늦게 실 행 될 수 있다.
상속 시
예제 코드:
public class SuperClass {
static {
System.out.println("Super static initialization block.");
}
public SuperClass() {
System.out.println("Super constructor.");
}
}
public class SubClass extends SuperClass {
static {
System.out.println("Sub static initialization block.");
}
public SubClass() {
System.out.println("Sub constructor.");
}
}
public class Main {
public static void main(String[] args) {
new SubClass();
}
}
실행 결과:
Super static initialization block.
Sub static initialization block.
Super constructor.
Sub constructor.
이 예 에서 하위 클래스 의 대상 을 예화 하고 클래스 가 불 러 오 면 클래스 를 초기 화 합 니 다.실행 시 시스템 은 하위 클래스 를 초기 화 할 때 부모 클래스 를 초기 화 해 야 하기 때문에 부모 클래스 의 정적 초기 화 블록 을 먼저 실행 한 다음 에 하위 클래스 의 정적 초기 화 블록 을 실행 한 다음 에 하위 클래스 대상 을 실례 화 할 때 부모 클래스 대상 을 먼저 예화 해 야 하기 때문에 보통 부모 클래스 초기 화 블록 - > 하위 클래스 초기 화 블록 - > 부모 클래스 구조 방법 - > 하위 클래스 구조 방법 순 으로 합 니 다.더 복잡 한 상황 에 부 딪 히 면 구체 적 인 분석 이 필요 하 다.
총결산
간단하게 요약 하면 정적 초기 화 블록 은 클래스 가 초기 화 될 때 한 번 실 행 됩 니 다. 보통 이러한 종류의 모든 다른 방법 보다 우선 합 니 다. 정적 필드 간 의 실행 순서 와 원본 코드 작성 순서 가 같 습 니 다.하위 클래스 정적 초기 화 블록 을 실행 하기 전에 부모 클래스 정적 초기 화 블록 을 실행 합 니 다.기타 복잡 한 상황 의 구체 적 인 문 제 를 구체 적 으로 분석 하 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.