📌초기화
일반적으로 객체가 생성된 후에 가장 먼저 하는 작업은 객체의 데이터를 초기값으로 설정하는 것이다.
Java에서는 생성자라는 개념을 사용하여 객체가 생성될 때마다 초기화 작업을 자동으로 실행한다.
📌생성자 (Constructor)
생성자는 일반 메소드와 아주 흡사하다. 다만 생성자 이름이 클래스 이름과 같고, 반환(return) 값을 가지지 않는다는 점이 다르다.
기본 생성자 (Default 생성자)
만약 클래스 작성시에 생성자를 하나도 만들지 않는 경우에는 자동적으로 메소드의 몸체 부분이 비어 있는 생성자가 만들어진다. 이를 디폴트 생성자라고 한다. 만약 생성자가 하나라도 선언되어 있으면 디폴트 생성자는 자동으로 추가되지 않는다. 즉, 기본 생성자가 컴파일러에 의해서 추가되는 경우는 클래스에 정의된 생성자가 하나도 없을 때 뿐이다.
여러 개의 생성자를 중복 정의(overloading)하는 것도 가능하다.
Calculator c1 = new Calculator(10, 20);
c1.sum();
c1.mul();
class Calculator{
int left, right;
public Calculator(int left){
this.left = left;
}
public Calculator(int left, int right){ //매개변수가 있는 생성자
this.left = left;
this.right = right;
}
public void sum() {
System.out.println(this.left + this.right);
}
public void mul() {
System.out.println(this.left * this.right);
}
}
※연산자 new가 인스턴스를 생성하는 것이지 생성자가 인스턴스를 생성하는 것이 아니다.
Card c = new Card();
//1.연산자 new에 의해서 메모리(heap)에 Card클래스의 인스턴스가 생성된다.
//2.생성자 Card()가 호출되어 수행된다.
//3.연산자 new의 결과로, 생성된 Card인스턴스의 주소가 반환되어 참조변수 c에 저장된다.
생성자에서 다른 생성자 호출하기
같은 클래스의 멤버들 간에 서로 호출할 수 있는 것처럼 생성자 간에도 서로 호출이 가능하다.
단, 다음 두 조건을 만족해야 한다.
- 생성자의 이름으로 클래스이름 대신 this를 사용한다.
- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.
class Car{
String color;
String gear Type;
int door;
Car(){
this("white", "auto", 4); //Car(String color,String gearType,int door)를 호출
}
Car(String color){
this(color,"auto",4);
}
Car(String c, String g, int d){
color=c;
gearType=g;
door=d;
}
// 'this'는 참조변수로 인스턴스 자신을 가리킨다.
Car(String color, String gearType, int door){
this.color=color;
this.gearType=gearType;
this.door=door;
}
}
this를 사용할 수 있는 것은 인스턴스 멤버뿐이다. static메소드에서는 인스턴스 멤버들을 사용할 수 없는 것 처럼, this 역시 사용할 수 없다.
- this : 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어 있다. 모든 인스턴스메서드에 지역변수로 숨겨진 채로 존재한다.
- this( ), this(매개변수) : 생성자, 같은 클래스의 다른 생서자를 호출할 때 사용한다.
this와 this( )는 비슷하게 생겼을 뿐 완전히 다르다. this는 '참조 변수'이고, this( )는 '생성자'이다.
생성자를 이용한 인스턴스의 복사
현재 사용하고 있는 인스턴스와 같은 상태를 갖는 인스턴스를 하나 더 만들고자 할 때 생성자를 이용할 수 있다.
Car(Car c){
color=c.color;
gearType=c.gearType;
door=c.door;
}
// 다음과 같이 나타낼 수 있다.
Car(Car c){
//Car(String color, String gearType, int door)
this(c.color, c.gearType, c.door);
}
정리
- 객체를 생성할 때 new 키워드와 함께 사용된다 ( ex) new Calculator(); )
- 생성자는 일반 함수처럼 기능을 호출하는 것이 아니라 객체를 생성하기 위해 new와 함께 호출 된다.
- 객체가 생성될 때 변수나 상수를 초기화 하거나 다른 초기화 기능을 수행하는 메소드를 호출한다. (생성자 호출)
- 생성자는 반환 값이 없고, 클래스의 이름과 동일하다.
📌초기화 블럭 (initialization block)
초기화 블럭에는 '클래스 초기화 블럭'과 '인스턴스 초기화 블럭' 두 가지 종류가있다.
- 클래스 초기화 블럭: 클래스 변수의 초기화에 사용된다.
- 인스턴스 초기화 블럭: 인스턴스 변수의 초기화에 사용된다.
초기화 블럭 생성하는 법
클래스 내에 단순히 블럭 {} 을 만들고 안에 코드를 넣으면 된다. 이때, 클래스 초기화 블럭은 인스턴스 초기화 블럭 앞에 단순히 static을 덧붙이기만 하면 된다.
Class BlockTest{
static{ //클래스 초기화 블럭
System.out.println("static { }");
}
{ //인스턴스 초기화 블럭
System.out.println("{ }");
}
public BlockTest(){
System.out.println("생성자");
}
public static void main(String[] args){
System.out.println("BlockTest bt = new BlockTest();");
BlockTest bt = new BlockTest();
System.out.println("BlockTest bt2 = new BlockTest();");
BlockTest bt2 = new BlockTest();
}
}
/*실행결과
static{ }
BlockTest bt = new BlockTest();
{ }
생성자
BlockTestbt2 = new BlockTest();
{ }
생성자
*/
멤버변수의 초기화 시기와 순서
클래스(static) 변수의 초기화시점 클래스가 처음 로딩될 때 단 한번 초기화 된다.
인스턴스 변수의 초기화시점 인스턴스가 생성될 때마다 각 인스턴스 별로 초기화가 이루어진다.
클래스(static) 변수의 초기화순서 기본값 → 명시적초기화 → 클래스 초기화 블럭
인스턴스 변수의 초기화순서 기본값 → 명시적초기화 → 인스턴스 초기화 블럭 → 생성자
class InitTest{
static int cv=1; //명시적 초기화
int iv = 1;
static { cv=2; } //클래스 초기화 블럭
{ iv=2; } //인스턴스 초기화 블럭 인스턴츠 생성될때마다 실행됨
InitTest(){ //생성자
iv=3;
}
}
/*
new InitTest();와 같이 인스턴스를 생성했을때 과정
▷클래스 초기화
기본값 cv : 0
명시적초기화 cv : 1
클래스 초기화 블럭 cv : 2
▷인스턴스 초기화
기본값 cv:2 iv:0
명시적초기화 cv:2 iv:1
인스턴스 초기화 블럭 cv:2 iv:2
생성자 cv:2 iv:3
****클래스변수는 항상 인스턴스변수보다 항상 먼저 생성되고 초기화 된다.****
*/
'Java' 카테고리의 다른 글
[Java] 제어자 , abstract , interface , 다형성, 내부 클래스 (0) | 2021.05.02 |
---|---|
[Java] 상속, overriding, overloading, super, final (0) | 2021.04.08 |
[Java] 객체와 클래스(멤버 변수/메소드) (0) | 2021.03.25 |
[Java] 배열 (0) | 2021.03.25 |
[Java] 조건문 & 반복문 (0) | 2021.03.24 |