객체 배열 안에 객체가 저장되는 것이 아니다.
객체의 주소가 저장된다.
즉, 객체 배열은 참조변수들을 하나로 묶은 참조 변수 배열이다.
Tv[] tvArr = new Tv[3];
for(int i = 0; i < tvArr.length; i++){
tvArr[i] = new Tv();
}
메서드를 호출할 때 매개변수의 타입의 기본형이라면 기본형 값이 복사가 되겠지만
참조형이면 인스턴스의 주소가 복사된다.
그렇기에 기본형으로 선언하면 단순히 저장된 값만 읽을 수 있지만(read)
참조형으로 선언하면 값의 저장된 주소를 알 수 있기 때문에 값을 읽고 변경하는 것 까지 가능하다.
(read&write)
클래스를 정의할 때, 어느 경우에 static을 사용해서 클래스 메서드로 정의해야하는 걸까?
인스턴스 메서드는 인스턴스 변수와 관련된 작업을 하는, 즉 메서드의 작업을 수행하는데 인스턴스 변수를 필요로 하는 변수이다.
그런데 인스턴스 변수는 인스턴스, 즉 객체를 생성해야만 만들어지므로 인스턴스 메서드 역시 인스턴스를 생성해야만 호출할 수 있다.
반면에 메서드 중에 인스턴스와 관계없는(인스턴스 변수나 인스턴스 메서드를 사용하지 않는) 메서드를 static 메서드로 정의한다.
class InitTest{
static int x; // 클래스 변수
int y = x; // 인스턴스 변수
void method(){
int i; // 지역 변수
int j = i; // 에러. 지역변수를 초기화하지 않고 사용.
}
}
멤버 변수(클래스 변수와 인스턴스 변수)와 배열의 초기화는 선택적이지만,
지역변수의 초기화는 필수적이다.
변수를 선언과 동시에 초기화하는 것을 명시적 초기화라고 한다.
가장 기본적이면서도 간단한 초기화 방법이므로 가장 우선적으로 고려되어야 한다.
class Car{
int door = 4;
Engine e = new Engine();
}
보다 복잡한 초기화 작업이 필요할 때는 '초기화 블럭' 또는 '생성자'를 사용해야 한다.
초기화 블럭을 작성하려면,
인스턴스 초기화 블럭은 단순히 클래스 내에 블럭 {}을 만들고, 그 안에 코드를 작성하면 된다.
클래스 초기화 블럭은 인스턴스 초기화 블럭 앞에 static을 붙이면 된다.
초기화 블럭 내에는 메서드 내에서와 같이 조건문, 반복문, 예외처리 구문 등을 자유롭게 사용할 수 있으며, 초기화 작업이 복잡하여 명시적 초기화만으로는 부족한 경우 초기화 블럭을 사용한다.
특히, 중요하게 생각해야 할 지점은, 생성자보다 인스턴스 초기화 블럭이 먼저 수행된다는 것이다.
인스턴스 변수의 초기화는 주로 생성자를 사용하고, 인스턴스 초기화 블럭은 모든 생성자에서 공통적으로 수행되어져야 하는 코드를 넣는데 사용된다.
Car(){
count++;
serialNo = count;
color = "White";
gearType = "Auto";
}
Car(String color, String gearType){
count++;
serialNo = count;
this.color = color;
this.gearType = gearType;
}
클래스의 모든 생성자에 공통적으로 수행되어야 하는 문장들이 있을 때, 이 문장들을 각 생성자마다 써주기보다는 인스턴스 블럭에 넣어주면 코드가 간결해진다.
{
count++;
serialNo = count;
}
Car(){
color = "White";
gearType = "Auto";
}
Car(String color, String gearType){
this.color = color;
this.gearType = gearType;
}