머리말
Java에서는 객체를 사용하기 전에 객체를 올바르게 초기화해야하며 Java 사양에 의해 규정되어 있습니다.
자동 초기화 (기본값)
클래스의 모든 기본 데이터 구성원이 초기화됩니다. 다음 예제를 실행하여 이러한 기본값을보십시오.
클래스 기본값 {부울 t; char c; 바이트 B; 짧은 s; int i; 긴 l; 플로트 F; Double D; public void show() { System.out.println("Basic type initialization value/n"+ "boolean<----->" + t +"/n" + "char<------>" + c +"/n" + "byte<------->" + b + "/n" + "short<------>" + s + "/n" + "int<------>" + i + "/n" + "long<------>" + l + "/n" + "float <------>" + f + "/n" + "double <----->" + d + "/n"); }} public class initValue {public static void main (String [] args) {default d = new default (); d.show (); }}【작동 결과】 :
기본 유형 초기화 값
부울 <-----> 거짓
char <----->
바이트 <-----> 0
짧은 <-----> 0
int <-----> 0
long <-----> 0
float <-----> 0.0
이중 <-----> 0.0
여기서, 숯 유형의 기본값은 null입니다.
비 프리맨티 데이터 유형의 경우 객체 핸들도 초기화됩니다.
클래스 사람 {개인 문자열 이름; // setter} class default {person p; public void show () {System.out.println ( "person <---->" + P); }} public class initValue {public static void main (String [] args) {default d = new default (); d.show (); }}【작동 결과】 :
사람 <-----> null
핸들 초기화 값이 NULL임을 알 수 있습니다. 이는 P의 초기화 값을 지정하지 않고 p.setName 과 유사한 메소드가 호출되면 예외가 발생 함을 의미합니다.
규정 초기화
초기 값을 변수에 직접 할당 해야하는 경우 변수를 정의하면서 값을 할당 할 수 있습니다.
클래스 기본값 {boolean t = true; char c = 'a'; 바이트 B = 47; 짧은 s = 0xff; int i = 24; 긴 l = 999; float f = 1.2f; 이중 D = 1.732; public void show () {system.out.println ( "boolean <----->" + t + "/n" + "char <----->" + c + "/n"/n " +"byte <-----> " + b +"/n " +"short <-----> " + s +"/n " +"int <-----> " + i +"/n " +" + " +" + " +" + " +" + " +" + " "float <------>" + f + "/n" + "double <------>" + d + "/n"); }} public class initValue {public static void main (String [] args) {default d = new default (); d.show (); }}한 가지 방법으로 초기화 할 수도 있습니다.
클래스 개인 {int i = set (); // ...}이러한 방법은 독립 변수를 사용할 수도 있습니다.
클래스 사람 {int i; int j = set (i); // ...} 빌더 초기화
빌더 초기화의 장점은 런타임 중에 초기화 값을 결정할 수 있다는 것입니다. 예를 들어:
계급 사람 {int age; 사람 () {age = 89; }}나이는 먼저 0으로 초기화 된 다음 89가됩니다. 이것은 모든 기본 유형과 객체에 대한 처리에 해당됩니다.
초기화 순서
클래스에서 초기화 순서는 변수가 클래스 내에서 정의되는 순서에 의해 결정됩니다. 변수 정의가 메소드 정의의 중간에 크게 퍼지더라도 모든 메소드 (생성자 포함)를 호출하기 전에 변수가 여전히 초기화됩니다. 예를 들어:
클래스 PET {PET (int Age) {System.out.println ( "PET (" + age + ")"); }} 클래스 사람 {pet t1 = new Pet (1); person () {system.out.println ( "--- person () ---"); T3 = 새로운 PET (33); } PET T2 = 새로운 PET (2); void show () {System.out.println ( "show ----- Running"); } PET T3 = New Pet (3);} 공공 계급 OrderOfinitialization {public static void main (String [] args) {person p = new person (); p.show (); }}【작동 결과】 :
애완 동물 (1)
애완 동물 (2)
애완 동물 (3)
--사람()---
애완 동물 (33) <br/>
쇼 ----- 달리기
위의 예에서, T1, T2 및 T3의 정의가 클래스 전체에 있지만, 초기화 순서는 T1, T2 및 T3의 정의 순서 (결과를 확인하기 위해 T1, T2 및 T3의 정의 순서에 의해 결정되며, 초기화는 건축기 실행보다 우선합니다. 사람 건축업자를 호출하면 T3이 재현됩니다.
정적 데이터의 초기화
데이터가 정적 인 경우 동일한 프로세스가 수행됩니다. 원시 유형이고 초기화되지 않은 경우 자체 표준 원시 유형 초기 값을 자동으로 얻습니다. 객체에 대한 핸들 인 경우 객체가 생성되고 연결되지 않으면 널 값을 얻습니다. 정의 시간에 초기화되면 정적 인 메소드는 정적이 아닌 값과 다릅니다. 정적은 하나의 저장 영역 만 갖습니다. 예를 들어:
클래스 보울 {bowl (int Marker) {System.out.println ( "bowl (" + Marker + ")"); } void f (int Marker) {system.out.println ( "f (" + Marker + ")"); }} 클래스 테이블 {정적 보울 b1 = 새로운 보울 (1); 표 () {system.out.println ( "table ()"); B2.f (1); } void f2 (int Marker) {system.out.println ( "f2 (" + Marker + ")"); } 정적 보울 b2 = 새로운 보울 (2);} 클래스 찬장 {bowl b3 = new bowl (3); 정적 보울 b4 = 새로운 보울 (4); cupboard () {system.out.println ( "cupboard ()"); b4.f (2); } void f3 (int Marker) {system.out.println ( "f3 (" + Marker + ")"); } static bowl b5 = new bowl (5);} public class staticinitialization {public static void main (String [] args) {System.out.println ( "메인에서 새 찬장 () 만들기"); 새 찬장 (); System.out.println ( "메인에서 새 찬장 () 만들기"); 새 찬장 (); T2.f2 (1); T3.f3 (1); } 정적 표 t2 = 새로운 테이블 (); 정적 찬장 t3 = 새로운 찬장 ();}【작동 결과】 :
그릇 (1)
그릇 (2)
테이블()
F (1)
그릇 (4)
그릇 (5)
그릇 (3)
찬장()
F (2)
메인에서 새 찬장 ()을 만듭니다
그릇 (3)
찬장()
F (2)
메인에서 새 찬장 ()을 만듭니다
그릇 (3)
찬장()
F (2)
F2 (1)
F3 (1)
정적 코드 블록
Java는 다른 정적 초기화 작업을 클래스의 특수 코드 블록으로 나눌 수 있도록합니다. 이 코드 블록은 정적 키워드와 정적 코드 블록이라는 메소드 본문의 형태입니다. 정적 코드 블록은 해당 클래스의 객체가 처음으로 생성되거나 해당 클래스에 속하는 정적 멤버가 처음으로 액세스 할 때만 실행됩니다. 예를 들어:
클래스 사람 {person (int age) {system.out.println ( "person (" + age + ")"); } void f (int age) {system.out.println ( "f (" + age + ")"); }} 클래스 사람 {정적 사람 P1; 정적 인 P2; 정적 {p1 = 새로운 사람 (1); p2 = 새로운 사람 (2); } persons () {system.out.println ( "persons ()"); }} public Class ExpricitStatic {public static void main (String [] args) {System.out.println ( "Inside Main ()"); persons.p1.f (18); // 1} 정적 인원 x = new Persons (); // 2 정적 인 y = 새로운 사람 (); // 2}1으로 표시된 줄에서 정적 객체 P1에 액세스하거나 라인 1이 댓글을 달고 2 행이 댓글을 달지 않으면 사람을위한 정적 초기화 모듈이 실행됩니다. 1과 2 모두 댓글을 달면 사람에게 사용되는 정적 코드 블록은 실행되지 않습니다.
정적 특성 및 정적 코드 블록 실행 순서
클래스 사람 {person (int age) {system.out.println ( "person ("+age+")"); }} 클래스 사람 {정적 사람 p = 새로운 사람 (2); // 1 정적 {p = 새로운 사람 (3); } 정적 사람 P = 새로운 사람 (2); // 2} public class compstaticInit {public static void main (String [] args) {} 정적 인원 x = new Persons ();}주석 1 고정 2 및 주석 2 고정 1의 분석에 따르면, 정적 특성 및 정적 코드 블록의 실행 순서는 인코딩 순서에 달려 있음을 알 수 있습니다. 앞서 나가는 사람은 먼저 처형됩니다.
비 정적 특성의 초기화
클래스 동물 {동물 (int Age) {System.out.println ( "동물 (" + age + ")"); } void f (int age) {system.out.println ( "f (" + age + ")"); }} 공개 클래스 NOTSTATICINIT {Animal A1; 동물 A2; {a1 = 새로운 동물 (1); A2 = 새로운 동물 (2); System.out.println ( "A1 & A2 초기화"); } notstaticInit () {System.out.println ( "NotStaticInit"); } public static void main (String [] args) {System.out.println ( "Inside Main ()"); NOTSTATICINIT X = NEW NOTSTATICINIT (); }}정적 코드 블록과 유사하게 비 정적 속성을 가진 익명 코드 블록의 초기화 순서는 인코딩 순서 에 따라 다릅니다.
상속 객체 초기화 프로세스
클래스 곤충 {int i = 1; int J; insect () {prt ( "i =" + i + ", j =" + j); j = 2; } static int x1 = prt ( "static insect.x1 초기화"); static int prt (string s) {system.out.println (s); 반환 3; }} 공개 클래스 딱정벌레는 곤충을 확장합니다 {int k = prt ( "beeklt.k 초기화"); 딱정벌레 () {prt ( "k =" + k); prt ( "j =" + j); } static int x2 = prt ( "static bootle.x2 초기화"); static int prt (string s) {system.out.println (s); 반환 4; } public static void main (String [] args) {prt ( "딱정벌레 생성자"); 딱정벌레 b = 새로운 딱정벌레 (); }}【작동 결과】 :
정적 곤충 .x1 초기화
static bootle.x2 초기화되었습니다
딱정벌레 생성자
i = 1, j = 0
Beeklt.k 초기화
k = 4
j = 2
딱정벌레에서 Java를 실행할 때 발생하는 첫 번째 일은 그 수업을 외부에서 찾는 로더입니다. 로딩 프로세스 중에 로더는 기본 클래스를 발견하므로 그에 따라로드됩니다. 이 프로세스는 기본 클래스의 객체가 생성되는지 여부에 관계없이 수행됩니다. 기본 클래스에 다른 기본 클래스가 포함되어 있으면 다른 기본 클래스가로드됩니다. 다음으로 루트베이스 클래스에서 정적 초기화를 수행 한 다음 다음 파생 클래스에서 실행합니다. 이는 미분 클래스의 초기화가 기본 클래스 멤버의 초기화에 달려 있기 때문입니다.
모든 클래스가로드되면 물체를 만들 수 있습니다. 첫째,이 객체의 모든 기본 데이터 유형은 기본값으로 설정되고 객체 핸들이 NULL로 설정됩니다. 그런 다음 기본 클래스의 빌더를 실행하십시오. 이 상황은 자동으로 수행됩니다 ( super(), 기본 클래스의 빌더는 Super를 통해 지정할 수도 있습니다). 기본 클래스 빌더가 완료되면 파생 된 클래스 인스턴스 변수는 원래 순서로 초기화되고 빌더의 나머지 신체 부위가 실행됩니다.
객체 생성 과정을 요약하십시오.
정적 실행은 클래스가로드 된 경우에만 수행됩니다.
비 정적은 인스턴스화 될 때만 실행되며 객체가 생성 될 때마다 실행됩니다.
정적 실행은 비 정적 전에 수행되며 기본 클래스 정적 정적은 파생 클래스보다 정적 실행보다 우선합니다.
정적 특성 및 정적 코드 블록의 실행 속성은 클래스에서의 위치에 따라 다르며 누가 먼저 실행합니다.
비 정적 특성 및 생성자 블록의 실행 순서는 클래스에서의 위치에 따라 다르며 그 이전에 실행됩니다.
요약
위의 소개를 통해 Java의 객체를 초기화하는 몇 가지 방법과 초기화 코드를 실행하는 방법을 이해하고 초기화되지 않은 변수를 사용할 수있는 상황도 소개합니다. 이러한 문제에 대한 자세한 이해를 얻은 후에는 인코딩의 위험을 피하기 위해 객체가 눈에 잘 띄기 전에 완전히 초기화되도록 할 수 있습니다.