Java의 정적 블록이 실행되지 않음
class Test{
public static void main(String arg[]){
System.out.println("**MAIN METHOD");
System.out.println(Mno.VAL);//SOP(9090);
System.out.println(Mno.VAL+100);//SOP(9190);
}
}
class Mno{
final static int VAL=9090;
static{
System.out.println("**STATIC BLOCK OF Mno\t:"+VAL);
}
}
static
클래스가로드 될 때 블록이 실행 된다는 것을 알고 있습니다. 그러나이 경우, 인스턴스 변수 내부 클래스 Mno
이다 final
때문에 그, static
블록은 실행되지 않는다.
왜 이렇게이다? 을 제거하면 final
제대로 작동합니까?
어떤 메모리가 먼저 할당 됩니까 , static final
변수 또는 static
블록입니까?
받는 사람에 의한 경우 final
액세스 수정 클래스는로드되지 않습니다, 그럼 어떻게 변수 GET 메모리 할 수 있습니까?
static final int
필드는 인 컴파일 시간 상수 와 그 값이 원점에 대한 참조없이 대상 클래스로 하드 코딩되고;- 따라서 메인 클래스는 필드를 포함하는 클래스의 로딩을 트리거하지 않습니다.
- 따라서 해당 클래스의 정적 초기화 프로그램이 실행되지 않습니다.
구체적으로 컴파일 된 바이트 코드는 다음과 같습니다.
public static void main(String arg[]){
System.out.println("**MAIN METHOD");
System.out.println(9090)
System.out.println(9190)
}
제거하자마자 final
더 이상 컴파일 타임 상수가 아니며 위에서 설명한 특수 동작이 적용되지 않습니다. Mno
클래스는 예상대로로드 및 실행하는 초기화 정적된다.
클래스가로드되지 않은 이유 VAL
는 final
AND 가 상수 표현식 (9090)으로 초기화되기 때문입니다 . 이 두 조건이 충족되는 경우에만 상수가 컴파일 시간에 평가되고 필요한 경우 "하드 코딩"됩니다.
컴파일 타임에 표현식이 평가되는 것을 방지하고 JVM이 클래스를로드하도록하려면 다음 중 하나를 수행 할 수 있습니다.
마지막 키워드를 제거하십시오.
static int VAL = 9090; //not a constant variable any more
or change the right hand side expression to something non constant (even if the variable is still final):
final static int VAL = getInt(); //not a constant expression any more static int getInt() { return 9090; }
If you see generated bytecode using javap -v Test.class
, main() comes out like:
public static void main(java.lang.String[]) throws java.lang.Exception;
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String **MAIN METHOD
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: sipush 9090
14: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
17: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
20: sipush 9190
23: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
26: return
You can clearly see in "11: sipush 9090
" that static final value is directly used, because Mno.VAL is a compile time constant. Therefore it is not required to load Mno class. Hence static block of Mno is not executed.
You can execute the static block by manually loading Mno as below:
class Test{
public static void main(String arg[]) throws Exception {
System.out.println("**MAIN METHOD");
Class.forName("Mno"); // Load Mno
System.out.println(Mno.VAL);
System.out.println(Mno.VAL+100);
}
}
class Mno{
final static int VAL=9090;
static{
System.out.println("**STATIC BLOCK OF Mno\t:"+VAL);
}
}
1)Actually you have not extends that Mno class so when compilation start it will generate constant of variable VAL and when execution start when that variable is needed its load thats from memory.so its not required your class reference so that static bock is not executed.
2)if A class extend that Mno class at that time that static block is included in A class if you do this then that static block is executed. for example.. public class A extends Mno{
public static void main(String arg[]){
System.out.println("**MAIN METHOD");
System.out.println(Mno.VAL);//SOP(9090);
System.out.println(Mno.VAL+100);//SOP(9190);
}
}
class Mno{
final static int VAL=9090;
static`{`
System.out.println("**STATIC BLOCK OF Mno\t:"+VAL);
}
}
As far as I know, it will be executed in order of appearance. For instance :
public class Statique {
public static final String value1 = init1();
static {
System.out.println("trace middle");
}
public static final String value2 = init2();
public static String init1() {
System.out.println("trace init1");
return "1";
}
public static String init2() {
System.out.println("trace init2");
return "2";
}
}
will print
trace init1
trace middle
trace init2
I just tested it and the statics are initialized (=> print) when the class "Statique" is actually used and "executed" in another piece of code (my case I did "new Statique()".
참고URL : https://stackoverflow.com/questions/16853747/static-block-in-java-not-executed
'developer tip' 카테고리의 다른 글
.Net 4.0의 새로운 튜플 유형이 값 유형 (구조체)이 아닌 참조 유형 (클래스) 인 이유 (0) | 2020.09.14 |
---|---|
numpy.array 동등성을 주장하는 가장 좋은 방법은 무엇입니까? (0) | 2020.09.14 |
Python-정확히 sklearn.pipeline.Pipeline은 무엇입니까? (0) | 2020.09.14 |
고정 된 영역을 제외하고 전체 화면을 어둡게합니까? (0) | 2020.09.14 |
JUnit과 Hamcrest를 함께 사용하는 방법은 무엇입니까? (0) | 2020.09.14 |