변수를 선언하고 처음으로 값을 저장하는 것을 변수의 초기화라고 한다.

변수의 초기화는 경우에 따라서는 필수적이기도 하고 선택적이기도 하지만, 가능하면 선언과 동시에 적절한 값으로 초기화 하는 것이 바람직하다.

멤버변수는 초기화를 하지 않아도 자동적으로 변수의 자료향에 맞는 기본값으로 초기화가 이루어지므로 초기화를 하지 않고 사용해도 되지만 지역변수는 사용하기 전에 반드시 초기화를 해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class InitTest {
int x;   <-- 멤버변수
int y = x; <--멤버변수 인스턴스 변수라고 함
 
void method1() {
int i; //지역변수 (메소드안에 존재하는 것은 지역변수) 초기화를 해야 한다.
int j = i; // 컴파일 에러발생 : 지역변수를 초기화하지 않고 사용했음.
}
}
 
//변수의 초기화
//변수를 선언하고 처음으로 값을 저장하는 것을 변수의 초기화라고 한다.
//변수의 초기화는 경우에 따라서는 필수적이기도 하고 선택적이기도 한다.
//가능하면 선언과 동시에 적절한 값으로 초기화 하는것이 바람직히다.
//멤버변수는 초기화를 하지 않아도, 자동적으로 변수의 자료형에 맞는 기본값으로 초기화가 이루어지므로
//초기화를 하지 않고 사용해도 되지만 지역변수는 사용하기 전에 반드시 초기화를 해야 한다.
 
 
cs

 

멤버변수의 초기화 방법- 클래스의 안에 들어 있는것을 멤버변수라고 한다.

 

★ 멤버변수의 초기화하는 방법

 

1. 명시적 초기화

2. 생성자

3. 초기화 블럭

인스턴스 초기화 블럭: 인스턴스변수를 초기화하는데 사용

클래스 초기화 블럭: 클래스변수를 초기화 하는데 사용

 

★ 명시적 초기화

변수를 선언과 동시에 초기화하는 것을 명시적 초기화라고 한다. 가장 기본적이면서도 간단한 초기화방법이므로 여러 초기화 방법 중에서 가장 우선적으로 고려되야 함

 

class Car{

int door=4; // 기본형(primitive type) 변수의 초기화

Engine e = new Engine(); //참조형(reference type)변수의 초기화

//..

}

 

명시적 초기화가 간단하고 명료하긴 하지만, 보다 복합한 초기화 작업이 필요할때는 "초기화 블럭(initialzation block)" 또는 생성자를 사용해야 한다.

 

초기화 블럭

초기화 블럭에는 "클래스 초기화 블럭"과 "인스턴스 초기화 블럭" 두가지 종류가 있다.

클래스 초기화 블럭은 클래스변수의 초기화에 사용되고, 인스턴스 초기화 블럭은 인스턴스변수의 초기화에 사용된다.

 

● 클래스 초기화 블럭- 클래스 변수들의 초기화에 사용된다.

● 인스턴스 초기화블럭- 인스턴스변수들의 초기화에 사용된다.

 

초기화 블럭을 작성하려면, 인스턴스 초기화 블럭은 단순히 클래스 내에 블럭{}을 만들고, 그안에 코드를 작성하기만 하면된다. 그리고, 클래스 초기화 블럭은 인스턴스 초기화 블럭 앞에 단순히 static을 덧붙이기만 하면 된다.

 

초기화 블럭 내에서는 메서드 내에서와 같이 조건문, 반복문, 예외처리구문 등을 자유롭게 사용할 수 있으므로, 초기화작업이 복잡하여 명시적 초기화 만으로는 부족한 경우 초기화 블럭을 사용한다.

 

클래스 초기화 블럭은 클래스가 메모리에 처음 로딩될때 한번만 수행되며, 인스턴스 초기화 블럭은 생성자와 같이 인스턴스를 생성할때 마다 수행된다. 그리고, 생성자보다는 인스턴스 초기화블럭이 먼저 수행된다는 사실도 기억해두자.!!

 

★ 클래스가 처음 로딩될때 클래스변수들이 메모리에 만들어지고, 바로 클래스 초기화블럭들이 클래스 변수들을 초기화하게 되는 것이다.

 

인스턴스변수의 초기화는 주로 생성자를 사용하기 때문에, 인스턴스 초기화 블럭은 잘 사용되지 않는다. 대신 클래스의 모든 생성자에서 공통적으로 수행되어져야 하는 코드가 있는 경우 생성자에 넣지 않고 인스턴스 초기화 블럭에 넣어두면 코드의 중복을 줄일수 있다.

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package Mon;
//Student_DB 학생DB를 통한 this 생성자의 연습 this 다른 생성자를 부를 때 사용하는 말
 
class Stu {
    String level;//대학교 1학년부터 4학년을 위해 표시
    protected int DB_Number;//학생들 마다 DB고유넘버
    String major;//주요 전공을 의미
    String professor;//각 전공별 주요교수를 의미
 
    //인스턴스 초기화를 위해 생성자를 만든다.
//생성자는 클래스의 이름과 동일하게 한다.
    Stu() {
        this("3"002"Computer_Engineering""Department_of_Computer_Science ");//여기서 다른 생성자를 호출한다.
    }
 
    Stu(String level) {
        this(level, 004"Computer_Engineering""Department_of_Computer_Science");
    }
 
    Stu(String level, int DB_Number, String major, String professor) {
        this.level = level;
        this.DB_Number = DB_Number;
        this.professor = professor;
        this.major = major;
        this.professor = professor;
    }
}
 
class Student_DB {
    public static void main(String[] args) {
        //최초 인스턴스를 생성해야 한다.
        Stu s1 = new Stu();
        //제대로 들어갔는지 확인하는 작업
        System.out.println("------------대학교 학생관리 시스템 예시--------------");
        System.out.println("대학교 몇학년?=" + s1.level);
        System.out.println("학생고유DB넘버?=" + s1.DB_Number);
        System.out.println("학생들의 주요전공?=" + s1.major);
        System.out.println("지도교수?=" + s1.professor);
 
        Stu s2 = new Stu("2");
        //생성자를 다르게 해서 호출하는 방법
        System.out.println("--------대학교 학생관리 시스템 예시-------2번째 방법");
        System.out.println("대학교 몇학년?=" + s2.level);
        System.out.println("학생고유DB넘버?=" + s2.DB_Number);
        System.out.println("학생들의 주요전공?=" + s2.major);
        System.out.println("지도교수?=" + s2.professor);
    }
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package Mon;
 
import com.sun.xml.internal.ws.api.ha.StickyFeature;
 
import java.util.SplittableRandom;
 
class Car {
    String color; //색상
    String gearType; //변속기종류-auto(자동),manual(수동)
    int door; //문의 개수
 
// ★★★생성자에서 다른 생성자를 호출하는 방법
// 생성자는 다른 생성자를 호출할수가 있으며 그방법은 this를 통해 결정을 한다.
// c1인 참조변수가 Car()라는 인스턴스를 생성하였고, Car()안에는 color,gearType,door 총3개의 변수가 존재하며 초기화가 아직 지정되지는 않았다.
// 인스턴스는 생성자를 무조건 하나만들어야 하기에 아래와 같이 매개변수가 없는 기본생성자가 만들어졌고, Car()라는 생성자는 인스턴스를 초기화를 한후,
//this를 호출한다. 여기서 this란 바로 밑에 존재하는 다른 매개변수가 존재하는 생성자를 호출한다.
//1번생성자에서 white,auto,4라는 숫자가 this를 통해 즉 2번을 호출했기 때문에 전달이 되고 white,auto,4는 color,gearType,door에 대입이 된다.
//그부분이 바로 this.color=color;
//this.gearType=type;
//this.door=door;를 의미한다.
//이후 이것을 확인하기 위해 System.out.pritln을 통해 확인이 가능하다.
 
//다른 방법으로는 인스턴스를 생성할때부터 매개변수의 값을 미리 지정을 하는 것이다.
//c2는 Car()를 참조하고 있으며, 이미 Car()라는 인스턴스에는 blue가 대입이 되어있고 매개 변수가 존재하는 생성자 Car(String color)에 대입이 된다.
//자연스럽게 blue는 color에 대입이 되고, 여기서 this는 다른 생성자인 Car(String color, String gearType, int door)을 호출한다.
//color에 이미 blue가 존재하기에 this(color을 하면 color에는 blue가 존재하고, gearType에는 auto, door에는 4가 대입하게 된다.
//이후 출력을 한다. 확인작업!!
    Car() { //1번 생성자
        this("white""auto"4);//Car(String door, String gearType, int door)를
        //호출
    }
 
    Car(String color, String gearType, int door) {//2번 생성자 이 두번째 생성자가 무조건 있어야 함!!!
        this.color = color;
        this.gearType = gearType;
        this.door = door;
    }
        Car(String color) {
 
        this(color, "auto"4);
    }
}
 
class CatTest2 {
    public static void main(String[] args) {
        Car c1 = new Car();
        Car c2 = new Car("blue");
 
        System.out.println("C1의 color=" + c1.door + ",gearType=" + c1.gearType + ",door=" + c1.door);
        System.out.println("c2의 color=" + c2.color + ",gearType=" + c2.gearType + ",door=" + c2.door);
    }
}
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package Fri;
 
class Car {
    String color;
    String gearType;
    int door;
 
    Car() {//매개변수가 없는 생성자 생성자의 이름은 클래스이 이름과 같아야함
    }//생성자는 인스턴스의 초기화작업에 사용된다.
    
    //무조건 하나의 생성자는 만들어야 하기 때문에 기본 생성자를 하나 만들었다. 기본 생성자의 경우 클래스의 이름과 똑같이 만들면 된다.
    //c1이 호출되는 구조
    1. 최초 Main이 호출이 된다. 
    2. Main은 Method Area라도 불리며 프로그램 실행 중 어떤 클래스가 사용되면, JVM은 해당 클래스의 클래스
       파일(*.class)을 읽어서 분석하여 클래스에 대한 정보 (클래스 데이터)를 Method Area에 저장한다.
       이때, 그 클래스의 클래스변수(class variable)도 이 영역에 함께 생성된다.
    3. c1은 참조변수로써 Car()를 가리키고 있다.
    4. 이때, Car()는 호출이 되는데 Car은 내용물은 다음과 같다.
       color, gearType, door 등등이 존재한다.
       인스턴스를 만들었기 때문에, 메인메서드에서는 호출이 가능하며 c1.color식으로 호출을 한다.
       인스턴스는 Heap(힙)이라 불리는 인스턴스가 생성되는 공간에서 생성되며, 프로그램 실행 중 생성되는 인스턴스
       는 모두 이곳에서 생성된다고 보면된다.
       즉, 인스턴스변수들이 생성되는 공간이다.
    5. 호출스택(Call Stack 또는 Execution Stack) 호출스택은 메서드의 작업에 필요한 메모리 공간을 제공한다.
       메서드가, 호출스택에 호출된 메서드를 위한 메모리가 할당되며, 이 메모리는 메서드가 작업을 수행하는 동안
       지역변수(매개변수 포함)들과 연산의 중간결과 등을 저장하는데 사용된다. 그리고, 메서드가 작업을 마치게 되
       면,  첫 번째 메서드의 바로 위에 두 번째 메서드를 위한 공간이 마련된다.
    6. 이때 첫번째 메서드는 수행을 멈추고, 두번째 메서드를 수행하게 된다.
       호출스택의 메모리가 반환된다.두번째 수행후 첫번째 메소드가 다시 재수행된다.
       즉, 메모리를 첫번째 메소드가 비워지면 두번째 놈이 차지 다시 수행후 첫번째 메소드가 차지 순...
    
    //매개변수가 존재하는 직관력이 높아지는 c2 방식의 생성자
    1. c1과 달리 c2는 더욱 직관력이 높이는 방법이다.
       똑같이 생성자를 만들기는 하지만, 매개변수가 존재한다.
    2. 때문에, 하나씩 지정할 필요는 없고, 타입에 맞춰서 넣기만 하면 끝
    3. 무슨말인가 하면 new Car("white","auto",4);
       당연히, white는 String의 c에 저장, auto도 g에 저장 이때 타입은 String 문자열임, 4는 int형
       그것들이 다시 color에 저장이 됨
       그럼 출력을 하고 싶다면 c2.color을 하고, c,g,d에 저장된것은 color,gearType,door에 저장되어 있기에
       출력된다. 
 
    /*Car(String c, String g, int d) {
        color = c;
        gearType = g;
        door = d;
    }*/
}
 
class CarTest {
    public static void main(String args[]) {
        Car c1 = new Car();
        c1.color = "white";
        c1.gearType = "auto";
        c1.door = 4;
 
       /* Car c2 = new Car("white", "auto", 4);*/
        System.out.println("c1의 color=" + c1.color + ",gearType=" + c1.gearType + ",door=" + c1.door);
       /* System.out.println("c2의 color=" + c2.color + ",gearType=" + c2.gearType + ",door=" + c2.door);*/
    }
}
cs

+ Recent posts