Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 코드로 시작하는 자바 첫걸음
- 2024 정보처리기사 시나공 필기
- 스프링 고급 - 스프링 aop
- 자바의 정석 기초편 ch14
- 자바의 정석 기초편 ch12
- 자바의 정석 기초편 ch11
- jpa 활용2 - api 개발 고급
- 스프링 mvc2 - 검증
- 게시글 목록 api
- @Aspect
- 자바의 정석 기초편 ch5
- 자바의 정석 기초편 ch9
- 자바의 정석 기초편 ch4
- 2024 정보처리기사 수제비 실기
- 스프링 mvc1 - 스프링 mvc
- 자바의 정석 기초편 ch8
- 자바의 정석 기초편 ch3
- 자바의 정석 기초편 ch7
- 스프링 입문(무료)
- 스프링 db2 - 데이터 접근 기술
- 스프링 mvc1 - 서블릿
- 자바의 정석 기초편 ch13
- 스프링 mvc2 - 타임리프
- jpa - 객체지향 쿼리 언어
- 자바의 정석 기초편 ch2
- 스프링 db1 - 스프링과 문제 해결
- 타임리프 - 기본기능
- 자바의 정석 기초편 ch6
- 자바의 정석 기초편 ch1
- 스프링 mvc2 - 로그인 처리
Archives
- Today
- Total
나구리의 개발공부기록
자바의 정석 기초편 ch7 - 24 ~ 26[참조변수의형변환,instanceof 연산자] 본문
유튜브 공부/JAVA의 정석 기초편(유튜브)
자바의 정석 기초편 ch7 - 24 ~ 26[참조변수의형변환,instanceof 연산자]
소소한나구리 2023. 11. 27. 14:001) 참조변수의 형변환
- 사용할 수 있는 멤버의 갯수를 조절 하는 것
- 기본형의 형변환은 값이 바뀌지만 참조변수(참조형)의 형변환은 값(참조값, 객체)이 바뀌는 것이 아님 - 중요
- 단지 객체를 참조하는 방식만 변경되는 것일 뿐임
- 상속관계와 구현관계(인터페이스를 구현한 클래스)에서 사용 가능
(1) 예제1
- FireEngine 객체를 생성하여 참조한 참조변수를 업캐스팅, 다운캐스팅 -> 모두 성공적으로 적용됨
- 업캐스팅: 자식 클래스의 객체를 부모 클래스의 타입으로 변환하는 것 -> 더 일반적인 타입으로 변환, 형변환 타입 생략 가능
- 다운캐스팅: 부모 클래스의 타입으로 참조된 자식 클래스의 객체를 자식 클래스의 타입으로 변환하는 것 -> 구체적인 타입으로 변환, 형변환 타입 생략 불가능
- 업캐스팅, 다운캐스팅을해도 참조값이 바뀌는 것이 아니라는 점
** 주의
- 애초에 부모 클래스 타입의 객체를 자손타입으로 형변환하거나, 부모클래스 타입의 객체를 참조하는 참조변수를 다운캐스팅하면 컴파일에서는 에러가 안나지만 실제 프로그램을 실행하면 ClassCastException 에러가 발생함 - 예제2 상황
class Ambulance { }
class Car { // 멤버가 4개인 Car클래스
String color;
int door;
void drive () {
System.out.println("부릉부릉");
}
void stop () {
System.out.println("끼이익");
}
}
class FireEngine extends Car { // 멤버가 5개인 FireEngine클래스(Car멤버 상속)
void water() {
System.out.println("water");
}
}
public class ex07_write2 {
public static void main(String srg[]) {
FireEngine f = new FireEngine(); // FireEngine 인스턴스 생성
// 업캐스팅: 자손타입의 참조변수를 조상의 타입으로 형변환 시에는 형변환타입을 생략 가능함
// 조상 클래스의 멤버만 사용 가능, water()사용 불가
Car c = f; // 참조변수 f를 Car타입의 c 참조변수로 형변환
// 다운캐스팅: 조상 타입의 참조변수지만 참조한 객체는 자손타입의 객체이므로 다운캐스팅이 가능
// 모든 클래스의 멤버 사용 가능
FireEngine f2 = (FireEngine)c;
// Ambulance a = (Ambulance)f; // 실행시 에러! 상속관계가 아닌 클래스간의 형변환은 불가능,
}
}
(2) 예제2 - 다운 캐스팅시 주의점
- 자손타입의 참조변수는 조상타입의 객체를 가르킬 수 없음 (형변환 에러 발생)
- 조상클래스 객체를 참조한 조상타입 참조변수를 자손클래스 타입으로 형변환(다운캐스팅)을 하면 컴파일에러는 나지않지만 실행하면 ClassCastException 에러가 발생(조상 클래스의 객체를 생성할 때 다운캐스팅해도 동일하게 에러남)
- 즉, 참조변수의 형변환이나 객체의 형변환 시 중요한 점은 참조변수가 가르키고있는 객체가 무엇인지가 중요하며 해당 객체가 가진 멤버의 집합이 참조변수의 타입이 가지고 있는 멤버의 집합을 모두 포함해야 함
- 형변환 시 타입 생략 여부를 고민하는 것은 그 이후에 문제임
class Car2 {
String color;
int door;
void drive () {
System.out.println("부릉부릉");
}
void stop () {
System.out.println("끼이익");
}
}
class FireEngine2 extends Car2 {
void water() {
System.out.println("water");
}
}
public class ex7_7 {
public static void main(String srg[]) {
// 객체 생성없이 참조변수를 null로 초기화만 하고 실행하면 NullPointerException 에러가 발생
Car2 car2 = null; // 참조변수를 null로 초기화
FireEngine2 fe2 = null;
fe2 = new FireEngine2(); // 자손 타입의 인스턴스 생성
fe2.water(); // 참조변수 f2e가 가리키는 객체의 water메서드 호출 -> OK
car2 = fe2; // 조상(Car2) 타입으로 형변환(형변환 생략 가능)
// car2.water(); // 컴파일에러, Car2타입의 참조변수는 water()를 호출 불가능
car2.drive(); // 참조변수 car2가 가리키는 객체의 drive메서드 호출 -> OK
fe2 = (FireEngine2)car2; // 다시 자손타입으로 형변환(형변환 생략 불가)
fe2.water(); // 참조변수 fe2가 가리키는 객체의 water메서드 호출 -> OK
// 형변환 에러 - 주의
// 조상타입인 실제 객체를 자손타입으로 형변환 후 실행하면 java.lang.ClassCastException 에러 발생
Car2 c2 = new Car2();
FireEngine2 f2 = (FireEngine2)c2; // 자손타입의 참조변수로 조상 객체를 가르킬 수 없음
f2.water(); // 컴파일에서는 문제없지만 실행시 에러 발생
// 자손타입의 참조변수로 조상의 객체를 참조할 수 없음
FireEngine2 f2 = new Car2(); // 컴파일 에러 발생
}
}
3) instanceof 연산자
- 참조변수의 형변환 가능여부 확인에 사용 -> 가능하면 true반환
- 다운캐스팅 에러 방지를 위해 형변환 전에 반드시 instanceof로 확인 후 형변환 하는 것을 권장함, 관례적으로 사용됨
FireEngine fe = new FireEngine();
System.out.printl(fe instanceof Object); // True (최고 조상으로 형변환 가능)
System.out.printl(fe instanceof Car); // True (조상으로 형변환 가능)
System.out.printl(fe instanceof FireEngine); // True
// 형변환 가능 여부를 메서드 형태로 만들어서 필요할때마다 호출하여 확인해도 좋음
// doWork()에 참조변수를 입력하면 형변환 가능 여부를 판단해서 true이면 로직을 수행함
static void doWork(Car c) {
if (c instanceof FireEngine) { // FireEngine 클래스타입으로 형변환이 가능한지 확인
FireEngine3 fe = (FireEngine) c; // water()메소드를 호출하기 위해 형변환
fe.water();
}
// 기타 코드들 ...
4) QnA
(1) Q. 참조변수의 형변환을 하는 이유?
- A. 사용할 수 있는 멤버의 갯수를 조절하기 위해서
(2) Q. instanceof연산자는 언제 사용?
- A. 참조변수를 형변환하기 전에 형변환 가능여부를 확인할 때, 객체의 타입을 확인할 때 사용
** 출처 : 남궁성의 정석코딩_자바의정석
'유튜브 공부 > JAVA의 정석 기초편(유튜브)' 카테고리의 다른 글
자바의 정석 기초편 ch7 - 31 ~ 34[추상 클래스, 추상 메서드, 추상클래스의작성1~2] (0) | 2023.11.28 |
---|---|
자바의 정석 기초편 ch7 - 27 ~ 30[매개변수다형성,여러종류의 객체를 배열로 다루기] (0) | 2023.11.27 |
자바의 정석 기초편 ch7 - 22 ~ 23 [캡슐화, 다형성] (1) | 2023.11.24 |
자바의 정석 기초편 ch7 - 17 ~ 21 [제어자, static, final, abstract, 접근제어자] (0) | 2023.11.24 |
자바의 정석 기초편 ch7 - 10 ~ 16[참조변수 super, 생성자super(), 패키지, 클래스 패스, import문, static import문] (2) | 2023.11.23 |