No. 01 |
|
| |
형변환(캐스팅, casting) |
형변환이란 변수 또는 상수의 타입을 다른 타입으로 변환하는 것을 말한다.
프로그램에서 값의 대입이나 연산을 수행할 때는 같은 타입끼리만 가능하다. 그래서 연산을 수행하기 전에 같은 타입으로 만들어야 하는데, 변수나 상수를 다른 타입으로 변환하는 것을 '형변환(casting)' 이라고 한다.
형변환은 물을 큰 그릇과 작은 그릇 사이에서 옮기는 것을 생각하면 이해가 쉽다. 각 타입을 크기가 다른 그릇이라고 생각해보자.
큰 그릇의 물을 작은 그릇으로 옮겨 담을 때 큰 그릇의 물이 작은 그릇이 담을 수 있는 양보다 많이 담겨 있다면 작은 그릇으로 옮겨 담을 때 물은 넘쳐서 원래의 양보다 줄어든다. 그러나 큰 그릇의 물이 작은 그릇이 담을 수 있는 양보다도 적게 담겨 있다면 작은 그릇으로 옮겨도 물의 양은 그대로 보존된다.
반대로 작은 그릇의 물을 큰 그릇으로 옮겨 담을 때 작은 그릇의 물의 양에 상관없이 큰 그릇으로 옮겨 담을 때는 물의 양은 그대로 보존된다.
형변환은 한 타입(그릇)의 데이터를 다른 데이터 타입(그릇)으로 옮겨 담는 것이다. 형변환에는 개발자가 지정하지 않아도 자동적으로 이루어지는 자동 형변환과 개발자가 명시해야만 이루어지는 강제 형변환이 있다.
형변환
(타입)피연산자
- 기본형에서 boolean을 제외한 나머지 타입들은 서로 형변환이 가능하다.
- 기본형과 참조형간의 형변환은 불가능하다.
- 자동 형변환과 강제 형변환 두가지가 있다.
No. 02 |
|
| |
자동 형변환 |
서로 다른 타입간의 대입이나 연산을 할 때 형변환으로 타입을 일치시켜서 하는것이 원칙이다.
그러나 다음과 같은 경우 자바의 컴파일러가 자동으로 형변환을 해주기 때문에 생략 가능하다. 작은 그릇의 물을 큰 그릇에 옮겨 담을 때는 항상 원래 물의 양이 보존되는 것처럼 작은 데이터 타입에서 큰 데이터 타입으로 형변환하여도 데이터의 손실 없이 그대로 보존될 수 있기 때문에 자동 형변환이 일어난다.
예를 들어 작은 그릇인 byte(1 byte)를 가장 큰 그릇인 double(8 byte)으로 데이터를 옮기면 손실 없이 그대로 보존된다.
▣ 자동 형변환의 규칙
왼쪽에서 오른쪽으로의 변환은 자동 형변환이 일어나며 반대 방향으로의 변환은 반드시 강제 형변환을 해주어야 한다.
실수형의 경우 소수점까지 표현하기 때문에 정수형보다 표현 범위는 크다고 할 수 있다. 다만 값의 크기는 정수형이 더 클 수 있으므로 형변환하는 경우 오차가 발생할 수 있다는 것을 주의해야 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class Casting { public static void main(String[] args) { int i = 100; char c = 'a'; int j = c; // char 타입에서 int 타입으로 자동 변환. double d = i; // int 타입에서 double 타입으로 자동 변환. System.out.println("int타입 변수 j의 값 : "+j); System.out.println("double타입 변수 d의 값: "+d); }//main }//class |
실행 결과
int타입 변수 j의 값 : 97
double타입 변수 d의 값 : 100.0
· 문자 'a'가 저장되어 있는 char타입 변수 c를 int형으로 대입할 때 자동 형변환된다. '어떻게 문자를 정수형으로 넣을 수 있을까?' 라는 의문이 있다. 이는 바로 'a'의 아스키 코드값인 97로 저장이 된다.
· int타입 변수 j를 double형으로 대입할 때도 마찬가지로 자동 형변환된다. 100의 정수 값이 소수점이 생긴 100.0으로 저장된 것을 볼 수 있다.
No. 03 |
|
| |
강제 형변환 (명시적 형변환) |
큰 그릇의 물을 작은 그릇에 옮겨 담는 것과 같다. 큰 그릇에 있는 물의 양에 따라 물이 넘칠수도 있고 보존될 수도 있다. 마찬가지로 큰 데이터 타입에서 작은 데이터 타입으로 옮길 때 데이터의 손실이 발생할 수도 아닐수도 있다.
데이터의 손실이 일어난다면 정확한 연산을 수행할 수 없기 때문에 예상하지 못한 결과를 얻을 수 있다. 그러므로 강제 형변환시 주의해서 형변환해야 한다.
◈ 예제 : 정수형간의 형변환
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class Casting { public static void main(String[] args) { //int -> byte 강제 형변환(값이 작을 경우) int i = 10; byte b = (byte)i; //강제 형변환을 하지 않으면 에러 발생. System.out.println("[int -> byte] i의 값 :"+i+" b의 값:"+b); //int -> byte 강제 형변환(값이 큰 경우) int j = 1000; byte c = (byte)j; //강제 형변환을 하지 않으면 에러 발생. System.out.println("[int -> byte] j의 값 :"+j+" c의 값:"+c); }//main }//class |
실행 결과
[int -> byte] i의 값 :10, b의 값:10
[int -> byte] i의 값 :1000, b의 값:-24
byte의 값의 범위에 있는 10의 값을 넣었을 경우 손실없으나, byte의 값의 범위를 넘는 경우 손실이 발생하여 예상하지 못한 값이 나온것을 볼 수 있다.
◈ 예제 : 실수형간의 형변환
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 | public class Casting { public static void main(String[] args) { //doulbe -> float 강제 형변환(float타입 범위 내 값) double d1 = 1.1234; float f1 = (float)d1; System.out.println("[double -> float] d1의 값 :"+d1+", f1의 값:"+f1); //doulbe -> float 강제 형변환(float타입 최소 값보다 작은 경우) double d2 = 1.0e-50; float f2 = (float)d2; System.out.println("[double -> float] d2의 값 :"+d2+", f2의 값:"+f2); //doulbe -> float 강제 형변환(float타입 최대 값보다 큰 경우) double d3 = 1.0e100; float f3 = (float)d3; System.out.println("[double -> float] d3의 값 :"+d3+", f3의 값:"+f3); //doulbe형과 float의 정밀도 차이 double d4 = 9.123456789; float f4 = (float)d4; System.out.println("[정밀도 차이] d4의 값 :"+d4+", f4의 값:"+f4); }//main }//class |
실행 결과
[double -> float] d1의 값 :1.1234, f1의 값:1.1234
[double -> float] d2의 값 :1.0E-50, f2의 값:0.0
[double -> float] d3의 값 :1.0E100, f3의 값:Infinity
[정밀도 차이] d4의 값:9.123456789, f4의 값:9.123457
· 범위 내 값에서 강제 형변환 할 경우 데이터의 손실없이 변환된다.
· float이 가질 수 있는 최소 값보다 작은 경우 0이 된다.
· float이 가질 수 있는 최대 값보다 큰 경우 무한대(infinity)가 된다.
· float의 범위 내 값이지만 소수점 아래 값에서의 정밀도 차이가 난다.
◈ 예제 : 정수형과 실수형 간의 형변환
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class Casting { public static void main(String[] args) { //float -> int 강제 형변환 float f1 = 12345.67f; int i1 = (int)f1; System.out.println("[float -> int] f1의 값 :"+f1+", i1의 값:"+i1); //double -> int 강제 형변환 double d1 = 12345.678; int i2 = (int)d1; System.out.println("[double -> int] d1의 값 :"+d1+", i2의 값:"+i2); }//main }//class |
실행 결과
[float -> int] f1의 값 :12345.67, i1의 값:12345
[double -> int] d1의 값 :12345.678, i2의 값:12345
· 실수형을 정수형으로 형변환시 소수점 이하 값은 버려진다.
'JAVA' 카테고리의 다른 글
[Java 11] 자바에서 키 입력(Scanner) (1) | 2017.11.20 |
---|---|
[Java 10] 자바의 출력문(println, printf) (2) | 2017.11.19 |
[Java 08] 문자열 - String (1) | 2017.11.18 |
[Java 07] 문자형 - char (0) | 2017.11.18 |
[Java 06] 데이터 타입 (1) | 2017.11.15 |