TIL-23-02-22
Updated:
참조변수의 형변환
- 참고하고 있는 인스턴스에서 사용할 수 있는 멤버의 갯수를 조절하는 것.
- 조상-자손 관계일때만 서로 형변환이 가능함.
- 캐스트연산자를 사용하며, 괄호()안에 변환하고자 하는 타입의 이름(클래스명)을 적어주면 된다.
class Car {
String color;
int door;
void drive() { // 운전하는 기능
System.out.println("drive, Brrrr~");
}
void stop() { // 멈추는 기능
System.out.println("stop!!!");
}
}
class FireEngine extends Car { // 소방차
void water() { // 물 뿌리는 기능
System.out.println("water!!!");
}
}
class Ambulance extends Car { // 앰뷸런스
void siren() { // 사이렌을 울리는 기능
System.out.prinln("siren~~");
}
}
Car car = null;
FireEngine fe = new FireEngine();
FireEngine fe2 = null;
car = fe; // car = (Car)fe;에서 형변환 생략됨. 업캐스팅
fe2 - (FireEngine)car; // 형변환을 생략불가. 다운 캐스팅
형변환 생략가능과 생략불가능한 경우
자손타입 -> 조상타입(업캐스팅) : 형변환 생략가능 </br> 조상타입 -> 자손타입(다운캐스팅) : 형변환 생략불가
- 업캐스팅의 경우, 참조변수가 다룰 수 있는 멤버의 개수가 실제 인스턴스가 갖고 있는 멤버의 개수보다 적거나 같을 것이 분명하기 때문에 형변환이 생략 가능함.
형변환 오류가 발생하는 경우(ClassCastException)
class CastingTest2 {
public static void main(String args[]) {
Car car = new Car();
Car car = null;
FireEngine fe = null;
car.drive();
fe = (FireEngine)car;
fe.drive();
car2 = fe;
car2.drive();
}
}
실행결과
drive, Brrrr~
java.lang.ClassCastException: Car at CastingTest2.main(CastingTest2.java:8)
- 컴파일은 성공하지만 실행 시 에러가 발생한다.
- 참조변수 car가 참조하고 있는 인스턴스가 Car타입(조상)이기 때문이다. 즉, 조상타입의 인스턴스를 자손타입의 참조변수로 참조하는 경우, 참조변수의 멤버가 인스턴스(객체) 멤버 갯수보다 많아 존재하지 않는 멤버를 사용할 가능성이 있으므로 형변환이 허용되지 않는다.
- 따라서 참조변수가 가리키는 인스턴의 타입이 무엇인지(실제 객체의 멤버 갯수) 확인하는 것이 중요하다.
instanceof연산자
- 참조변수의 형변환 가능여부를 확인하는데 사용한다. instanceof연산의 결과가 true이면 해당 타입으로 형변환이 가능하다.
- 주로 조건문에 사용되며 instanceof의 왼쪽에는 참조변수, 오른쪽에는 타입(클래스명)이 피연산자로 위치한다.
- instanceof연산자는 자기 자신, 조상까지 true를 반환한다.
class InstanceofTest {
public staic void main(String args[]) {
FireEngine fe = new FireEngine();
if(fe instanceof FireEngine) {
System.out.println("This is a FireEngine instance.");
}
if(fe instanceof Car) {
System.out.println("This is a Car instance.");
} //fe의 인스턴스타입이 Car가 아님에도 true인 것은 Car타입(조상타입)으로 형변환이 가능하다는 것을 뜻한다.
//따라서 실제 인스턴스 타입을 알려주는 것이 아니다.
if(fe instanceof Object) {
System.out.println("This is a Object instance.");
}
System.out.println(fe.getClass().getName()); // 클래스의 이름을 출력
}
}
class Car { }
class FireEngine extends Car { }
// 실행결과
This is a FireEngine instance.
This is a Car instance.
This is a Object instance.