본문 바로가기

프로그래밍언어/Java

[Java 중급] 래퍼 클래스 - 기본형의 한계

기본형의 한계


자바는 객체 지향 언어이다. 그런데 자바 안에 객체가 아닌 것이 있다. int, double 같은 기본형이다. 따라서 객체 지향 프로그램의 장점을 살릴 수 없다. 대표적인 예로 메서드를 제공할 수 없고, null 값을 가질 수 없다는 점이 그렇다. 

 

예제


기본형의 한계를 이해하기 위해, 두 값을 비교해서 다음과 같은 결과를 출력하는 간단한 예제를 보자. 

 

package lang.wrapper;

public class MyIntegerMethodMain0 {

    public static void main(String[] args) {
        int value = 10;
        int i1 = compareTo(value, 5);
        System.out.println("i1 = " + i1);

        int i2 = compareTo(value, 10);
        System.out.println("i2 = " + i2);

        int i3 = compareTo(value, 20);
        System.out.println("i3 = " + i3);

    }

    public static int compareTo(int value, int target) {
        if(value < target) {
            return -1;
        } else if(value > target) {
            return 1;
        } else {
            return 0;
        }

    }
}

 

=> 이 예제에서 value와 비교 대상 값을 compareTo() 라는 외부 메서드를 사용한다. 자기 자신인 value와 다른 값을 연산하는 것이기 때문에 항상 자기 자신의 값인 value가 사용된다. 이런 경우 만약 value가 객체라면 value 객체 스스로 자기 자신의 값과 다른 값을 비교하는 메서드를 만드는 것이 더 유용할 것이다.  

 

직접 만든 래퍼 클래스


기본형을 감싸서 만드는 클래스를 래퍼 클래스(Wrapper class)라 한다. 직접 만들어보자. 

public class MyInteger {

    private final int value;

    public MyInteger(int value) {
        this.value = value;
    }

    public int compareTo(int target) {
        if(value < target) {
            return -1;
        } else if(value > target) {
            return 1;
        } else {
            return 0;
        }
    }
    
    @Override
    public String toString() {
        return String.valueOf(value);
    }
}

=> 자기 자신이 들고있는 value와 외부의 값을 비교한다. 

 

메인메서드를 만들어보자. 

public class MyIntegerMethodMain1 {

    public static void main(String[] args) {
        MyInteger myInteger = new MyInteger(10);
        int i1 = myInteger.compareTo(5);
        int i2 = myInteger.compareTo(10);
        int i3 = myInteger.compareTo(20);

        System.out.println("i1 = " + i1);
        System.out.println("i2 = " + i2);
        System.out.println("i3 = " + i3);
    }
}

=> 실행결과는 똑같다. 첫번째 예제와의 차이점은 자기 자신의 메서드를 제공하기 때문에 더 객체지향적이다. 

 

 

기본형과 null


기본형은 항상 값을 가져야 한다. null 값을 넣고 싶을 때는 기본형을 사용할 수가 없다. 


public class MyIntegerNullMain0 {

    public static void main(String[] args) {
        int[] intArr = {-1, 0, 1, 2, 3};
        System.out.println(findValue(intArr, -1));
        System.out.println(findValue(intArr, 0));
        System.out.println(findValue(intArr, 1));
        System.out.println(findValue(intArr, 100));
    }

    private static int findValue(int[] intArr, int target) {
        for (int value : intArr) {
            if(value == target) {
                return value;
            }
        }

        return -1;
    }
}

 

실행결과

=> -1을 찾았을 때 -1을 반환한다. 100을 찾으면 값이 없기 때문에 -1을 반환한다. 둘을 어떻게 구분하는가? 값을 찾지 못할 경우에도 숫자를 반환해야 되므로 -1을 반환하도록 처리하면서 이런 문제가 발생한 것이다. 

 

객체의 경우 null 값을 반환할 수 있다. 


public class MyIntegerNullMain1 {

    public static void main(String[] args) {
        MyInteger[] intArr = {new MyInteger(-1), new MyInteger(0), new MyInteger(1)};
        System.out.println(findValue(intArr, -1));
        System.out.println(findValue(intArr, 0));
        System.out.println(findValue(intArr, 1));
        System.out.println(findValue(intArr, 100));
    }

    private static MyInteger findValue(MyInteger[] intArr, int target) {
        for (MyInteger myInteger : intArr) {
            if(myInteger.getValue() == target) {
                return myInteger;
            }
        }

        return null;
    }
}

 

=> 값이 없을 때 null을 사용할 수 있다. 

 

 

 

* 인프런 '김영한의 실전 자바 - 중급 1편'을 참고하여 작성하였습니다.