📝 끄적끄적/🖥️ 자바의 정석

[자바의 정석] 생성자, 변수/멤버 변수의 초기화

현주먹 2023. 9. 22. 23:41

챕터 6 끝!

19개의 영상에서 많은 걸 배웠다.

7까지 달려보자 아자자

 

생성자(contrunctor)

인스턴스가 생성될 때마다 호출되는 ‘인스턴스 초기화 메서드

인스턴스 초기화 메서드란? 인스턴스 변수 초기화하는 메서드이다.

Time t = new Time(); //객체 생성
t.hour = 12; //초기화
t.minute = 34; //초기화
t.second = 56; //초기화

 

이것을 간단하게 할 수 없을까

Time t = new Time(12, 34, 56); //생성자 호출

 

특징

  • 이름이 클래스 이름과 같아야 한다.
  • 리턴값이 없다.(void 안 붙임)
  • 모든 클래스는 반드시 생성자를 가져야 한다.

 

기본 생성자

  • 매개 변수가 없는 생성자
  • 생성자가 하나도 없을 때만, 컴파일러가 자동 추가
    • 매개변수가 있는 생성자를 만든 후, 기본 생성자를 호출하면 에러발생

 

생성자 this()

  • 생성자에서 다른 생성자 호출할 때 사용
  • 다른 생성자 호출 시 첫 줄에서만 사용가능
class Car2 {
	String color;		// 색상
	String gearType;	// 변속기 종류 - auto(자동), manual(수동)
	int door;			// 문의 개수

	Car2() {
		this("white", "auto", 4); /* 코드 중복 최소화해서 이렇게 쓰면됨 */
		//color = "white" 
		//gearType = "auto"
		//door = 4;
	}

	Car2(String color) {
		this(color, "auto", 4);
	}
	Car2(String color, String gearType, int door) {
		this.color    = color;
		this.gearType = gearType;
		this.door     = door;
	}
}

 

 

참조변수 this

  • 인스턴스 자신을 가리키는 참조변수
  • 인스턴스 메서드(생성자 포함)에서 사용가능
  • 지역변수와 인스턴스 변수를 구별할 때 사용
  • 모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재한다.
class Car3 {
	String color;		// 색상
	String gearType;    // 변속기 종류 - auto(자동), manual(수동)
	int door;			// 문의 개수

	Car3(String c, String g, String d) {
		color = c; 
		gearType = g;
		door = d;
	}
}

 

여기서는 지역변수가 이름이 다르고, 같은 클래스 내라서 `this.` 가 생략된 것.

원래는 아래처럼 `this`를 붙여줘야 한다.

class Car3 {
	String color;		// 색상
	String gearType;    // 변속기 종류 - auto(자동), manual(수동)
	int door;			// 문의 개수

	Car3(String color, String gearType, int door) {
		this.color    = color;
		this.gearType = gearType;
		this.door     = door;
	}
}

 

 

this와 this()

`this`와 생성자 `this()`는 완전히 다른 것이다.
`this`는 ‘참조 변수’이고 `this()`는 ‘생성자’이다.

 

 

변수의 초기화

  • 지역변수는 수동 초기화 해야 함(사용 전 꼭!!)
  • 인스턴스 변수는 자동 초기화됨
class InitTest {
	int x; //인스턴스 변수
	int y = x; //인스턴스 변수

	void method1() {
		int i; //지역변수
		int j = i; //에러. 지역변수를 초기화하지 않고 사용
}

 

 

왜 지역변수는 수동 초기화 해줘야 하는가?

지역변수는 호출스택에 재사용이 빈번한 메모리다.

= 아주 짧은 시간 동안 같은 메모리 공간을 쓰고 또 쓰고 하는데, 호출될 때마다 메모리를 0으로 초기화하면 성능이 떨어지기 때문에 성능을 높이기 위해 새로운 값을 덮어씌우는 식을 초래한다.

그래서 사용자에게 수동 초기화하게 돼있다.

 

그럼 인스턴수 변수는 왜 자동으로 초기화 될까?

인스턴스 변수는 유지기간이 지역변수에 비해 길기 때문에 자동 초기화된다.

= 객체는 여러 변수들을 묶어 놓은 거기 때문에 자동 초기화 안 하면 해줘야 될 게 너무 많아서도 있다.

 

 

멤버 변수(인스턴스 변수, 클래스(static) 변수)의 초기화

1. 명시적 초기화 (=)

class Car {
	int door = 4; //기본형 변수의 초기화
	Engine e = new Engine(); //참조형 변수의 초기화
}

`Engine e;`

-> null이 들어가 있는 것. 만들어지기만 하지 객체가 있는 게 아니다.

 

2. 초기화 블록

   a. 인스턴스 초기화 블록 : { }

   b. 클래스 초기화 블럭 : static { }

class StaticBlockTest 
{
	static int[] arr = new int[10];

	static {
		for(int i=0;i<arr.length;i++) {
			// 1과 10사이의 임의의 값을 배열 arr에 저장한다.
			arr[i] = (int)(Math.random()*10) + 1;
		}
	}

	public static void main(String args[]) {
		for(int i=0; i<arr.length;i++)
			System.out.println("arr["+i+"] :" + arr[i]);
	}
}

 

 

3. 생성자

Car(String color, String gearType, int door) {
		this.color    = color;
		this.gearType = gearType;
		this.door     = door;
	}

 

 

결론

인스턴스 변수는 생성자로
클래스 변수는 static { }로

 

 

클래스 변수의 초기화 시점

  • 클래스가 처음 로딩될 때 단 한번(메모리에 올라갈 때)

 

인스턴스 변수 초기화 시점

  • 인스턴스가 생성될 때마다
class InitTest {
	static int cv = 1; //명시적 초기화
	int iv = 1;        //명시적 초기화
	
	static { cv = 2; } //클래스 초기화 블럭
	{ iv = 2; }        //인스턴스 초기화 블럭

	InitTest() { //생성자
		iv = 3;
	}
}

 

차례대로 1 -> 7이 순서다.