[Java] Final 배열과 정렬

조갱·2021년 4월 15일
1

개요

  • 책을 읽었는데 개쪄는걸 발견했다.

질문

  • 다음과 같은 코드는 정상적으로 실행이 될까?
import java.util.*;
public class Main {
    public static void main(String[] args) throws Exception {
        final int[] numbers = {-3, -5, 1, 7, 4, -2};
        Arrays.sort(numbers); // final인데 정렬이??
    }
}

정답

  • 일단 개쪄는걸 봤다고 했으니, 정상적으로 실행이 된다.

원리

  • 우선, 참조 타입(Reference Type) 변수와, 원시 타입(Primitive Type) 변수에 대해 알아야 한다.
  • 우리가 기본적으로 알고있는 int, float, bool, long...과 같은 변수는 원시 타입(Primitive Type) 변수이다.
  • 참조 타입(Reference Type)은, 객체(Object), 배열(Array), Integer/Long 과 같은 Wrapper Class에 해당한다.
  • 그리고, final한 참조 타입 변수는 다른 주소를 가리킬 수 없을 뿐, 그 대상 인스턴스 객체의 값을 수정하지 못한다는 의미가 아니다.
  • 따라서, numbers 변수가 다른 배열을 가리키지 못할 뿐, 가지고 있는 배열 내부의 값은 수정할 수 있다.

응용

  • 그렇다면, 내부의 값도 바꾸지 못하는 배열은 없을까?

    • 배열에서는 찾지 못했지만, list에서는 가능한 것 같다.
    • Collections.unmodifiableList 를 통해 sort 가 불가능한 list를 만들 수 있어보인다.
    import java.util.*;
    public class Main {
    public static void main(String[] args) throws Exception {
        /*final int[] numbers = {-3, -5, 1, 7, 4, -2};
        Arrays.sort(numbers);*/
    
    	List<Integer> list = new ArrayList<>();
    	list.add(1);
    	list.add(-1);
    	list.add(3);
    	list.add(9);
    
    	list = Collections.unmodifiableList(list);
    	Collections.sort(list);
    
          }
      }
  • Integer/Long과 같은 Wrapper Class도 참조 타입이니깐, final로 선언해도 가능하지 않을까?

    • 정답부터 얘기하면, 불가능하다.
    • 이는 Boxing, Unboxing 의 개념에 대해 알아야한다.
    • 간단하게 얘기하면, Integer 와 같은 Wrapper Class에는 직접적으로 값을 쓰지 못한다.
    • Wrapper Class에 값을 쓰기 위해선, int와 같은 원시 타입(Primitive Type)으로 언박싱(Unboxing)을 해줘야만 한다.
    • Unboxing을 하는 순간, 해당 변수가 가리키는 래퍼런스가 변경되므로 불가능하다!

출처

천방지축 Developer Note

profile
A fast learner.

0개의 댓글