정적 변수 초기화 순서
1. 간단한 규칙
먼저 가장 일반적인 Java 코드를 살펴 보겠습니다.
공개 클래스 테스트 {public static test1 t = new test1 (); 공개 정적 int a = 0; 공개 정적 int b; public static void main (String [] arg) {System.out.println (test.a); System.out.println (test.b); }} class test1 {public test1 () {test.a ++; test.b ++; }}콘솔의 출력 결과가 무엇인지 추측합니다.
좋아, 아마도 당신은 아래 결과를 추측했을 것입니다. 그래서 당신은 여전히 Java에 익숙합니다.
다음과 같이 코드를 복사하십시오. 0 1
위의 결과가 출력 인 이유를 이해하지 못하면 말씀 드리겠습니다.
Java 정적 변수 초기화는 다음 규칙을 따릅니다.
이 글을 읽은 후에는 테스트 값이 세 번 바뀌 었음을 이해할 것입니다.
선언 될 때 0으로 설정 >> test1 :: test1이 1 >> test로 설정되어 0으로 초기화됩니다.
2. 복잡한 규칙
이것을 이해하면 아래 코드를보십시오.
공개 클래스 A {public static int b = ba; public static a plus = new a ( "a"); public static final int finalint = (int) (math.random ()*100); public static b p = new b ( "a"); 공개 정적 최종 문자열 FinalStr = "FinalStr"; 공개 정적 최종 정수 Finalinteger = New Integer (10); 공개 정적 int a = 1; 공개 정적 B C = NULL; public a (string) {System.out.println ( "----------- 시작 a :: a --------------"); System.out.println ( "a :: a, from ="+from); System.out.println ( "a :: a, ab ="+ab); System.out.println ( "A :: A, A.FinalInt ="+A.FinalInt); System.out.println ( "a :: a, ba ="+ba); System.out.println ( "a :: a, b.plus ="+b.plus); System.out.println ( "---------------: a --------------"); } public static void main (String [] arg) {System.out.println ( "main, ab ="+ab); System.out.println ( "main, bt ="+bt); System.out.println ( "main, ca ="+ca); }} 클래스 B {public static int t = aa; public static a plus = new a ( "b"); 공개 정적 int a = 1; public b (string) {System.out.println ( "----------- 시작 B :: B ---------------------------------------------------------------- System.out.println ( "b :: b, from ="+from); System.out.println ( "b :: b, ba ="+ba); System.out.println ( "b :: b, aa ="+aa); System.out.println ( "b :: b, ap ="+ap); System.out.println ( "b :: b, a.plus ="+a.plus); System.out.println ( "B :: B, A.FinalInt ="+A.FinalInt); System.out.println ( "B :: B, A.FinalInt ="+A.FinalInt); System.out.println ( "B :: B, A.FinalInt ="+A.FinalInt); System.out.println ( "B :: B, A.FinalInt ="+A.FinalInt); System.out.println ( "B :: B, A.FinalInteger ="+A.FinalInteger); System.out.println ( "B :: B, A.FinalStr ="+A.FinalStr); System.out.println ( "----------------: b -------------"); }} class C {public static final a = new A ( "C");}여전히 출력 결과를 추측 할 수 있습니까? 나는 테스트하는 동안 그것을 썼다. 그래서 나는 그것을 추측하지 않았다. 하하
콘솔 출력 결과는 다음과 같습니다.
-----------------------------: a :: a, from = ba :: a, ab = 0a :: a, a.finalint = 0a :: a, ba = 0a :: a, b.plus = null -------------------------------------------------- A, = A : A, = A, A, A : A : A : A : A : A : A : A : A : A : A : A : A : A : A : A : A : A : A : A : A : A : A : A :: a.finalInt = 0a :: a, ba = 1a :: a, b.plus=a@a90653-------------------------------------------------------------------------------------------------- BA = 1B :: B, AA = 0B :: B, AP = NULLB :: B, BA = 1B :: B --------------- B :: B를 시작합니다. A.finalInt = 61B :: B, A.FinalInteger = NULLB :: B, A.FINALTR = FINALSTR -----------------: B -------------------------------------------------------------------------- A :: A :: A, AB = 1A :: A, A.Final = 61A :: B.plus=a@a90653--------------: a -------------------- Main, Ca = a@61de33
당신은이 결과를 추측하지 못했습니다, 하하.
프로그램의 실행 결과를 하나씩 설명하는 데 많은 시간이 걸립니다. 여기서는 규칙을 직접 작성한 다음 Java STATIC 변수 초기화가 이어집니다.
첫 번째 단락의 규칙은 여전히 유효하지만 건전하지는 않습니다.
정적 데이터의 초기화
정적 자격 필드를 추가하는 것은 소위 클래스 필드입니다. 즉,이 필드의 소유자는 객체가 아니라 클래스임을 의미합니다. 얼마나 많은 개체가 생성 되더라도 정적 데이터의 사본은 하나뿐입니다.
정적 필드는 항상 클래스에서 초기화 된 다음 일반 필드가 초기화됩니다. 그런 다음 생성자를 초기화하십시오. 그러나이 클래스의 객체가 생성되지 않으면 객체는 초기화되지 않으며 한 번만 실행됩니다.
다음 코드에서와 같이, 정적 성형 클래스에서 정적 테이블 테이블 = new Table (); 먼저, 테이블 객체가 초기화되지 않으면 초기화되지 않습니다.
클래스 보울 {bowl (int Marker) {print ( "bowl (" + Marker + ")"); } void f1 (int Marker) {print ( "f1 (" + Marker + ")"); }} 클래스 테이블 {static bowl bowl1 = new Bowl (1); 표 () {print ( "table ()"); bowl2.f1 (1); } void f2 (int Marker) {print ( "f2 (" + Marker + ")"); } 정적 보울 bowl2 = 새 보울 (2);} 클래스 찬장 {Bowl Bowl3 = New Bowl (3); 정적 보울 보울 4 = 새로운 보울 (4); 찬장 () {print ( "cupboard ()"); bowl4.f1 (2); } void f3 (int Marker) {print ( "f3 (" + Marker + ")"); } static bowl bowl5 = new Bowl (5);} 공개 클래스 정적 성형 {public static void main (String [] args) {print ( "메인에서 새 찬장 () 만들기"); 새 찬장 (); print ( "메인에서 새 찬장 () 만들기"); 새 찬장 (); 표 .f2 (1); 찬장 .f3 (1); } 정적 테이블 테이블 = 새 테이블 (); 정적 찬장 찬장 = 새로운 찬장 ();}산출:
그릇 (1) 그릇 (2) 테이블 () F1 (1) 그릇 (4) 그릇 (5) 그릇 (3) 찬장 () F1 (2) MainBowl (3) Cupboard () F1 (2) Mainbowl (3) Cupboard () F1 (2) F2 (1) F3 (1)에서 새 찬장 () 만들기
표시된 정적 초기화 (즉, 정적 블록)
정적 브레이스에 여러 초기화 문을 두는 것을 정적 블록이라고합니다. 실제로, 그것은 여러 정적을 작성하여 함께 쓰여졌으며, 본질은 동일합니다. 객체가 처음으로 생성 된 경우에만 실행되거나 클래스 필드에 처음으로 액세스 할 수 있습니다.
클래스 컵 {컵 (int Marker) {print ( "컵 (" + 마커 + ")"); } void f (int Marker) {print ( "f (" + Marker + ")"); }} 클래스 컵 {정적 컵 컵 1; 정적 컵 컵 2; 정적 {cup1 = 새로운 컵 (1); cup2 = 새로운 컵 (2); } cups () {print ( "cups ()"); }} public Class ExpricitStatic {public static void main (String [] args) {print ( "Inside Main ()"); Cups.cup1.f (99); // (1)} // 정적 컵 cups1 = new Cups (); // (2) // 정적 컵 cups2 = new Cups (); // (2)}산출:
Main Main () 컵 (1) 컵 (2) F (99)
비 정적 인스턴스 초기화
이것에 대해 할 말이 없습니다. 그것은 단지 일반 초기화 일뿐입니다. 순서대로 실행되며 여러 번 실행할 수 있습니다.
클래스 머그 {mug (int Marker) {print ( "mug (" + Marker + ")"); } void f (int Marker) {print ( "f (" + Marker + ")"); }} 공개 클래스 머그 {머그 mug1; 머그 뮤즈 2; {mug1 = 새로운 머그 (1); mug2 = 새로운 머그 (2); print ( "mug1 & mug2 초기화"); } mugs () {print ( "mugs ()"); } mugs (int i) {print ( "mugs (int)"); } public static void main (string [] args) {print ( "inside main ()"); 새로운 머그잔 (); print ( "new Mugs () 완료"); 새로운 머그잔 (1); 인쇄 ( "새 머그잔 (1) 완료"); }}Main Main () 머그 (1) 머그 (2) mug1 & mug2 초기화 mugs () new mugs () 완성 머그 (1) 머그 (2) mug1 & mug2 초기화 무두질 (int) 새 머그잔 (1) 완료