사이먼's 코딩노트
[Java] 형변환 문제풀이 본문
- Java 형변환과 관련된 문제를 풀어봅시다.
- 추가로 문제를 풀어보면서 수동 박싱/언박싱과 자동 박싱/언박싱의 개념도 함께 알아봅시다.
- Main 메서드에 작성된 코드를 보고 에러가 발생하지 않도록 수정 및 클래스와 메서드를 추가 작성해봅시다.
[문제 1]
- 아래 코드를 보고 숫자를 저장하는 저장소 클래스를 구현해봅시다.
public class Main {
public static void main(String[] args) {
저장소 a저장소 = new 저장소();
a저장소.저장(10);
int 결과 = a저장소.주세요();
System.out.println(결과);
// 출력 : 10
}
}
[문제 1 정답]
- 아래 코드는 Main 메서드를 제외한 저장소 클래스만 작성하였습니다.
- Main 메서드는 수정된 곳이 없다는 점 참고해주세요.
class 저장소 {
int data;
void 저장(int a) {
data = a;
}
int 주세요() {
return data;
}
}
- Main 메서드를 살펴보면 저장소 클래스에는 저장()과 주세요() 메서드가 있다는 것을 알 수 있다.
- 저장() 메서드는 매개변수로 정수 값을 받고, 주세요() 메서드는 넘겨주는 인자값은 없지만 값이 저장되는 결과라는 변수가 int 타입이기 때문에 메서드의 타입을 int로 선언해야한다.
- 로직은 다음과 같다 저장() 메서드를 통해 10이라는 정수를 저장하고 주세요() 메서드를 호출하여 10이라는 숫자를 결과에 저장하는 것이다.
- 저장소 클래스에서는 전역 변수인 data를 선언하고 저장() 메서드를 통해 data에 넘겨받은 인자 값을 넣어주고, 주세요() 메서드를 호출할 때 data를 return 하도록한다.
[문제 2]
- 아래 코드를 보고 저장소를 만들고 i의 값을 저장한 후 다시 받아보도록 코드를 구현해봅시다.
public class Main {
public static void main(String[] args) {
int i = 10;
System.out.println(i);
// 출력 : 10
}
}
class 저장소 {
Object data;
void 저장(Object o) {
data = o;
}
Object 주세요() {
return data;
}
}
[문제 2 정답]
public class Main {
public static void main(String[] args) {
int i = 10;
// 구현 시작
저장소 a저장소 = new 저장소();
a저장소.저장(i);
i = (int)a저장소.주세요();
// 구현 끝
System.out.println(i);
// 출력 : 10
}
}
class 저장소 {
Object data;
void 저장(Object o) {
data = o;
}
Object 주세요() {
return data;
}
}
- 먼저 저장소를 만들기 위해 [저장소 a저장소 = new 저장소()]를 작성하였다.
- 그리고 저장소의 저장() 메서드를 통해 i의 값 10을 Object 타입인 변수 o에 저장하였다.
- 이 때 저장소에 있는 data 변수의 타입은 모든 래퍼클래스와 객체를 받을 수 있는 Object 타입이다.
- 저장소의 주세요() 메서드를 호출하면 메서드 내에 return 값이 Object 타입의 data 변수이기 때문에 해당 값을 다시 int 타입인 변수 i에 저장하기 위해서는 강제 형변환이 필요하다.
- 그래서 a저장소.주세요() 호출 시 앞에 (int)를 작성하여 int 타입인 변수 i에 안전하게 해당 값을 저장한다.
[문제 3]
- 아래 코드를 보고 다양한 데이터를 저장할 수 있는 저장소 클래스를 구현해봅시다.
- 해당 문제는 박싱/언박싱의 개념을 적용하여 풀어봅시다.
public class Main {
public static void main(String[] args) {
저장소 a저장소 = new 저장소();
int i = 10;
Integer iObj = new Integer(i);
a저장소.저장(iObj);
iObj = a저장소.주세요();
i = iObj.intValue();
System.out.println(i);
// 출력 1
사람 a사람1 = new 사람();
a저장소.저장(a사람1);
a사람1 = a저장소.주세요();
a사람1.걷다();
// 사람이 걷습니다.
}
}
[문제 3 정답]
public class Main {
public static void main(String[] args) {
저장소 a저장소 = new 저장소();
int i = 10;
Integer iObj = new Integer(i);
a저장소.저장(iObj);
iObj = (Integer)a저장소.주세요(); // 수정
i = iObj.intValue();
System.out.println(i);
// 출력 1
사람 a사람1 = new 사람();
a저장소.저장(a사람1);
a사람1 = (사람)a저장소.주세요(); // 수정
a사람1.걷다();
// 사람이 걷습니다.
}
}
class 저장소 {
Object data;
void 저장(Object v) {
data = v;
}
Object 주세요() {
return data;
}
}
class 사람 {
void 걷다() {
System.out.println("사람이 걷습니다.");
}
}
- 먼저 박싱과 언박싱의 역할을 알아보자
- 박싱(Boxing) 은 사전적으로 상자에 넣다는 의미이고 언박싱(UnBoxing)은 사전적으로 상자에서 꺼낸다는 의미이다.
- 박싱은 원시 타입의 값을 해당하는 래퍼클래스의 객체로 변환하는 것을 의미한다.
- 박싱은 직접 래퍼클래스의 생성자를 호출하여 수행할 수 있지만 Java 5 버전 이후로 자동 박싱이라는 기능을 통해 해당 과정을 자동으로 처리할 수 있게 됐다.
- 위 코드에서 Main 메서드를 살펴보면 [Integer iObj = new Integer(i)] 의 부분이 수동 박싱의 역할을 한다. int 타입의 변수 i의 값을 해당하는 Integer 래퍼클래스의 객체로 변환시키는 작업이다.
- 그 다음 저장() 메서드를 통해 iObj의 값을 Object 타입인 data에 저장하고, 주세요() 메서드를 통해 다시 값을 저장할 때는 (Integer) 강제 형변환을 사용한다. 다시 말해 리턴 받는 타입은 Object형 리모콘이지만, 그것을 Integer 리모콘화 하겠다는 의미이다.
- 마지막으로 박싱 후 언박싱의 작업을 해야한다. 언박싱은 래퍼클래스의 객체를 원시 타입의 값으로 변환하는 것을 의미한다.
- 위 코드에선 [i = iObj.intValue()] 의 부분이 수동 언박싱의 역할을 한다. Integer라는 래퍼클래스의 객체 iObj를 원시 타입의 값인 int i으로 변환시키는 작업이다.
[문제 4]
- 아래 코드를 보고 사람 객체가 동물, Object에 연결된 후 다시 사람 리모콘에 연결하여 말할 수 있도록 코드를 구현해봅시다.
public class Main {
public static void main(String[] args) {
동물 a동물 = new 사람();
a동물.말하다();
Object o = a동물;
사람 a사람 = o;
a사람.말하다();
}
}
[문제 4 정답]
public class Main {
public static void main(String[] args) {
동물 a동물 = new 사람();
a동물.말하다();
Object o = a동물;
사람 a사람 = (사람)o; // 수정
a사람.말하다();
}
}
abstract class 동물 {
abstract void 말하다();
}
class 사람 extends 동물 {
void 말하다() {
System.out.println("말하다.");
}
}
- 문제에 제시된 Main 메서드를 통해 동물과 사람 클래스를 생성하고 a동물 래퍼런스 변수가 사람 객체와 연결되어 있기 때문에 동물과 사람 클래스를 서로 상속의 관계로 정의한다.
- Object 타입을 가진 변수 o를 선언하고 변수 o에 a동물이 가지고 있는 사람 객체 리모콘을 저장한다.
- 변수 o는 사실 객체이기만 하면 아무런 문제가 없는 변수이다.
- 그 다음 a사람이라는 래퍼런스 변수를 생성하여 해당 변수에 o가 가지고 있는 사람 객체 리모콘을 연결해줘야 한다.
- 이 때 변수 o는 Object 타입이고 a사람이 봤을 때는 o가 사람 객체 리모콘을 가지고는 있지만 확실하게 사람인지를 믿지 못하는 상황이다.
- 그래서 (사람) 을 작성하여 반드시 강제 형변환을 해줘야 에러없이 프로그램이 작동한다.
반응형
'Java > Java' 카테고리의 다른 글
[Java] ArrayList (2) | 2024.03.18 |
---|---|
[Java] 배열 / toString / equals / StringBuilder (2) | 2024.03.14 |
[Java] 형변환(래퍼클래스 / Object) (0) | 2024.03.13 |
[Java] 문자열을 다루는 String 클래스 메서드 (2) | 2024.03.13 |
[Java] static (0) | 2024.03.12 |