자바의 자료형 시스템은 기본 자료형, 참조 자료형 두가지로 나누어진다. 모든 자료형애는 대응되는 참조 자료형이 있는데 객체화된 기본 자료형이라고 불린다. boolean, int, double의 객체화된 기본 자료형은 Boolean, Integer, Double이다.
자바1.5 부터 자동 객체화(autoboxing)과 자동 비객체화(auto-unboxing)가 언어의 일부가 되었다. 이 기능들은 기본 자료형과 객체 표현형 간의 차이가 있으므로, 둘 가운ㄷ 무엇을 사용하고 있는 지를 아는 것이 중요하며, 어떤 것을 사용할지 신중하게 결정해야 한다.
기본 자료형 VS 객체화된 기본 자료형
1. 기본 자료형은 값만 가지지만 객체화된 기본 자료형은 값 외에도 신원(identity)을 가진다. 객체화된 기본 자료형은 같더라도 identity가 다를 수 있다.
2. 기본 자료형에 저장되는 값은 전부 기능적으로 완전한 값이지만, 객체화된 기본 자료형에 저장되는 값에는 그 이외에도 아무 기능이 없는 값, 즉 null이 하나 있다.
3.기본 자료형은 시간이나 공간요구량 측면에서 일반적으로 객체 표현형보다 효율적이다.
연산자 ==는 객체 참조를 통해 두 객체의 신원을 비교한다. a1과 a2는 같은 1의 값을 비교한다고 생각하여 true를 리턴한다고 생각하지만 결과는 false이다. 객체화된 기본 자료형에 == 연산자를 사용하는 것은 거의 항상 오류라고 봐야 한다.
1 2 3 4 5 6 | public static void main(String[] args) { Integer a1 = new Integer(1);//Auto-unboxing Integer a2 = new Integer(1);//Auto-unboxing System.out.println(a1 == a2); } |
이 문제를 고치려면 객체화된 기본 자료형에 대응하는 기본 자료형을 선언하여 두 변수를 이용하여 값을 비교하면 된다. 그러면 문제가 되는 신원 비교를 피할 수 있다.
아래 예제는 i == 42를 계산하려고 할 때 NullPointerException을 발생시킨다. 문제는 i가 Integer라는 것이다. 모든 참조 객체는 초기화 값이 null 이다. 위의 프로그램이 계산될 때 비교하는 것은 Integer 객체와 int 값이다. 거의 모든 경우에 기본 자료형과 객체화된 기본 자료형을 한 연산 안에 엮어 놓으면 객체화된 기본 자료형은 자동으로 기본 자료형으로 변환된다.
1 2 3 4 5 6 7 8 9 10 | public final class Test { static Integer i; public static void main(String[] args) { if ( i ==42 ) System.out.println("Unbelievable"); } } |
아래 프로그램은 예상보다 훨씬 느리다 지역 변수 sum을 객체화된 기본 자료형을 이용했기 때문이다. 오류나 경고 없이 컴파일 되는 프로그램이지만 변수가 계속해서 객체화와 비객체화를 반복하기 때문에 성능이 느려진다.
1 2 3 4 5 6 7 8 | public static void main(String[] args) { Long sum = 0L; for(long i=0; i < Integer.MAX_VALUE; i++) { sum += i; } System.out.println(sum); } |
객체화된 기본 자료형은 언제 사용할까 ?
컬렉션의 요소, 키, 값으로 사용할 때. 컬렉션에는 기본 자료형을 넣을 수 없으므로, 객체화된 자료형을 써야한다. 리플렉션을 통해 메서드를 호출할 때도 객체화된 기본 자료형을 사용해야 한다.
요약하자면 가능하다면 기본 자료형을 사용하라는 것이다. 자동 객체화는 번거로운 일을 주여주긴 하지만, 객체화된 기본 자료형을 사용할 때 생길 수 있는 문제들까지 없애주진 않는다. 객체화된 기본자료형과 기본 자료형을 한 표현식 안에 뒤섞으면 비객체화가 자동으로 일어나며, 그 과정에서 NullPointerexception이 발생할 수 있다.
'Effective Java > 8장 일반적인 프로그래밍 원칙들' 카테고리의 다른 글
Effective Java #51 문자열 연결 시 성능에 주의하라 (0) | 2018.10.03 |
---|---|
Effective Java #50 다른 자료형이 적절하다면 문자열 사용은 피하라 (0) | 2018.10.03 |
Effective Java #48 정확한 답이 필요하다면 float와 double은 피하라 (0) | 2018.10.03 |
Effective Java #47 어떤 라이브러리가 있는지 파악하고, 적절히 활용하라 (0) | 2018.09.20 |
Effective Java #46 for 문보다는 for-each 문을 사용하라 (0) | 2018.09.19 |