Language/Java

Promotion(자동형변환)과 Casting(명시적형변환), Upcasting vs Downcasting

settong 2024. 12. 5. 09:24
반응형

Promotion

promotion은 작은 크기의 자료형에서 큰 크기의 자료형으로 자동 변환되는 것을 의미한다.
'암시적형변환', '자동형변환'이라고도 한다.

int i = 100;
long l = i; // int -> long으로 자동 변환
float f = l; // long -> float으로 자동 변환

 

 

위의 코드에서 int 타입의 변수 ilong 타입의 변수 l로,
long 타입의 변수 lfloat타입의 변수 f로 자동 형변환 된다.
더 큰 크기의 자료형으로 변환되어 데이터 손실이 발생하지 않기 때문에 자동 변환되어도 안전하다.

참고로 + 연산자를 사용 시, 하나 이상의 피연산자가 String 타입이면, 다른 모든 피연산자도 String타입으로 promotion 된다.

 

public class StringPromotionExample {
    public static void main(String[] args) {
        int number = 42;
        double decimal = 3.14;
        boolean bool = true;

        // 하나 이상의 피연산자가 String 타입이면 다른 모든 피연산자도 String 타입으로 변환됨
        String result1 = "Number: " + number;
        String result2 = "Decimal: " + decimal;
        String result3 = "Boolean: " + bool;

        // 여러 피연산자를 포함하는 예시
        String result4 = "Combined: " + number + ", " + decimal + ", " + bool;

        System.out.println(result1); // "Number: 42"
        System.out.println(result2); // "Decimal: 3.14"
        System.out.println(result3); // "Boolean: true"
        System.out.println(result4); // "Combined: 42, 3.14, true"
    }
}




 


Casting

한 타입의 변수를 다른 타입으로 명시적으로 변환하는 것을 의미한다.
이는 '명시적 형변환'이라고도 한다.

double d = 100.04;
long l = (long) d; // double -> long으로 명시적 변환
int i = (int) l; // long -> int로 명시적 변환

위의 코드에서, double 타입의 변수 dlong 타입의 변수 l로,
long 타입의 변수 lint 타입의 변수 i로 명시적으로 변환된다.
이 과정에서는 데이터 손실이 발생할 수 있다.



 

 


Upcasting과 Downcasting

객체지향 프로그래밍에서 클래스 간의 형변환을 할 때 Upcasting 또는 Downcasting이라고 한다.
특히 상속 관계에 있는 클래스들 간의 형변환을 말한다.

Upcasting

서브 클래스 타입을 슈퍼 클래스 타입으로 변환하는 것을 의미한다.
이는 암시적 형변환이며, 항상 안전하다.

class Parent {
    void run() {
        System.out.println("Parent's");
    }
}

class Child extends Parent {
    void run() {
        System.out.println("Child's");
    }
}

public class Main {
    public static void main(String[] args) {
        Child cild = new Child();
        Parent parent = child; // Upcasting
        Parent.run(); // "Child's" 출력
    }
}

 

위 예시에서 Child 객체 childParent 타입으로 업캐스팅 되어 Parent 타입의 변수 parent에 할당된다.
Parent.run()을 호출하면 실제로는 Child 클래스의 run() 메서드가 호출된다.

 

 

Downcasting

슈퍼 클래스 타입을 서브 클래스 타입으로 변환하는 것을 의미한다.
이는 명시적 형변환이며, 안전하지 않을 수 있다.
다운캐스팅이 잘못될 경우 ClassCastException이 발생할 수 있다

class Parent {
    void run() {
        System.out.println("Parent's");
    }
}

class Child extends Parent {
    void run() {
        System.out.println("Child's");
    }
    void hello() {
        System.out.println("Hello");
    }
}

public class Main {
    public static void main(String[] args) {
        Parent parent = new Child(); // Upcasting
        Child child = (Child) parent; // Downcasting
        child.run(); // "Child's" 출력
        child.hello(); // "Hello" 출력
    }
}

   

Parent 타입의 변수 parentChild 객체를 참조하고 있으며,
이를 Child 타입으로 다운캐스팅하여 Child 타입의 변수 child에 할당한다.
다운캐스팅 후에는 Child 클래스의 메서드인 hello()를 호출할 수 있습니다.

 

❗️주의 사항

  • Downcasting은 이전에 upcasting된 객체에 대해서만 안전하게 수행할 수 있다.
  • instanceof 연산자를 사용하여 안전한 downcasting을 수행할 수 있다. 
  • if (parent instanceof Child) { Child child = (Child) parent; }
728x90
반응형