Language/Java

형 변환(Type Casting)

snowkit 2022. 6. 12. 22:18

업캐스팅(Upcasting)

기본 자료형

  • 더 큰 자료형으로 변환
    • Floating Point 자료형(float, double)은 Fixed Point 자료형(byte, short, char, int, long)보다 훨씬 더 넓은 범위를 표현할 수 있지만, 정확도를 보장하는 범위를 넘어서면 오차가 발생한다
  • 데이터 손실 없는 경우
    • byte → 더 큰 자료형(short, int, long, float, double)
    • short → 더 큰 자료형(int, long, float, double)
    • char → 더 큰 자료형(int, long, float, double)
    • int → long, double
  • 데이터 손실 있는 경우
    • int, long → float: ±16,777,216(=2²⁴) 이후 오차 발생
      • float의 가수부는 23비트지만, 항상 존재하는 암묵적 1을 포함하여 최대 24비트 오차 없이 표현 가능
        • 예시: 6.75 = 110.11₂ = 1.1011₂×2²
        • 가수 1.1011 에서 소수점 이하 부분인 1011만 저장
        • 읽어올 땐 1. 자동으로 추가
    • long → double: ±9,007,199,254,740,992(=2⁵³) 이후 오차 발생
      • double의 가수부는 52비트지만, 항상 존재하는 암묵적 1을 포함하여 최대 53비트 오차 없이 표현 가능
      • int는 32비트를 사용하므로 double로 변환 시 데이터 손실이 발생하지 않는다

클래스

  • 서브 클래스 인스턴스슈퍼 클래스 타입으로 참조
  • 데이터 손실이 일어나지 않음
    • 클래스의 형 변환은 참조 타입만 변경할 뿐, 객체는 여전히 서브 클래스의 인스턴스이기 때문
Child child = new Child();
Parent parent = child;

다운캐스팅(Downcasting)

기본 자료형

  • 더 작은 자료형으로 변환
  • 데이터 손실 발생 가능성 있으므로 주의
int i = 1000000;
short s = 30000;
s = (short) i;
System.out.println(s);// 16960

클래스

  • 슈퍼 클래스 타입으로 참조하고 있는 서브 클래스 인스턴스를 다시 서브 클래스 타입으로 참조
  • 데이터 손실이 일어나지 않음
    • 클래스의 형 변환은 참조 타입만 변경할 뿐, 객체는 여전히 서브 클래스의 인스턴스이기 때문
Parent parent = new Child();
Child child = (Child) parent;

형 변환 타입

자동 형 변환(Implicit type conversion)

정의

  • 컴파일러가 자동으로 다른 자료형으로 변환하는 것
    • C언어에서 int num = 3.14;의 경우 num 변수엔 소수점을 제외한 정수 부분만 저장된다(데이터 손실)
    • Java에서 int num = 3.14;의 경우 컴파일 에러가 발생한다

프로모션(Type promotion)

  • 더 큰 자료형으로 자동 업캐스팅
  • Java에서 자동 형 변환은 프로모션만 지원한다

산술 변환(Usual arithmetic conversion)

정의

  • 피연산자의 타입이 다른 경우, 하나로 일치시켜야 하기 때문에 연산 전 자동 형 변환 하는것

규칙

  1. int보다 작은 타입이 있으면 전부 int로 변환 후 계산한다
    • byte, short, char
  2. int보다 큰 타입이 있으면 전부 큰 타입으로 변환 후 계산한다
    • long, float, double

연산자

  • 피연산자가 1개면 단항 연산자
    • ++, --, +, -, ~, !, (type)
      • ++a, --a, +a, -a, ~a, !a, (int)a
  • 피연산자가 2개면 이항 연산자
    • 대부분의 연산자
      • a + b, a * b, a % b
  • 피연산자가 3개면 삼항 연산자
    • a ? b : c

산술 변환이 일어나지 않는 경우

  • 모든 연산에서 산술 변환이 일어나지만 다음 세 가지 경우는 산술 변환이 일어나지 않는다
    • 쉬프트 연산자(<<, >>)
    • 증감 연산자(++, --)
    • 리터럴 간의 연산
      • 실행 과정동안 변하는 값이 아니기 때문
      • 컴파일 시 컴파일러가 계산해서 상수로 대체하여 코드를 효율적으로 만든다

자동 형 변환 예시

byte a = 10;
byte b = 20;

// 컴파일 오류 발생
// 연산 결과가 int이므로 더 작은 byte 타입에 저장 불가
byte wrong = a + b;

// 정상 실행
// 리터럴 간의 연산은 int로 변환되지 않고 컴파일러가 계산
byte d = 3 + 5;

강제 형 변환(Explicit type conversion)

정의

  • 사용자가 직접 명시하여 다른 자료형으로 변환하는 것
  • 업캐스팅(Upcasting), 다운캐스팅(Downcasting) 둘 다 가능

강제 형 변환 예시

byte a = 10;
byte b = 20;

// 정상 실행 (업캐스팅)
// byte를 int로 강제 형 변환
// 자동 형 변환되기 때문에 의미없는 코드
int c = (int) a;

// 정상 실행 (다운캐스팅)
// 실제 연산 결과인 int를 byte로 강제 형 변환했기 때문에 byte 타입에 저장 가능
// 만약 byte 표현 범위(-128~127)를 넘어가는 경우 데이터 손실 발생
byte c = (byte) (a + b);

'Language > Java' 카테고리의 다른 글

오버라이딩(Overriding), 오버로딩(Overloading)  (0) 2022.07.17
초기화 블록(Initialization block)  (0) 2022.07.17
배열(Array)  (0) 2022.07.17
소수점 자르기  (0) 2022.06.14
문자형(char)  (0) 2022.06.13