티스토리 뷰

기수 정렬을 구현하던 중, Queue 로 이루어진 배열을 생성하는 과정에서
NullPointerException 이 발생해서 왜 그런지 찾아보다가 이 포스트를 작성하게 되었다.

Java 의 데이터 타입

원시 타입 (Primitive type) 과 참조형 타입 (Reference type)

Java의 변수들은 두 가지 타입 중 하나를 갖는다.

 

1. 원시 타입: 아래 표는 원시 타입의 종류들을 설명한다. 아래로 갈수록 더 많은 데이터를 담을 수 있는 타입이다.

 

이름 비트 수 초기화 syntax 선언만 했을 시 초기 값
byte 8 byte b = 100; 0
short 16 short s = 30,000; 0
int 32 int i = 100,000,000; 0
long 64 long l = 100,000,000,000,000; 0
float 32 float f = 1.456f; (뒤에 f 붙임) 0.0
double 64 double f = 1.456789012345678; 0.0
char 16 char c = ‘c'; \u0000′ or null
boolean 1 boolean b = true; false

 

원시 타입의 특징

 

  • 새로운 값을 할당하면 변수의 원래 값이 새 값으로 대체된다.
  • 모든 원시 타입 변수는 차지할 수 있는 메모리가 한정되어 있다. 
  • 특정 default 값으로 초기화된다. (로컬에서 선언한 변수는 초기화되지 않는다.)
  • 선언과 동시에 초기화가 다른 과정을 거치지 않고 바로 될 수 있다.

2. 참조형 타입: 원시 타입이 아닌 모든 변수들은 참조형 타입을 갖는다.

 

자바에서 자주 사용되는 참조형 타입은 Queue, Deque, PriorityQueue, List, Stack, Map, Set, LinkedList 등이 있다.

 

참조형 타입의 특징

 

  • 객체의 위치나 참조값을 컴퓨터 메모리에 저장하는 변수의 타입이다. 프로그램 내의 객체를 참조한다.
  • 흔히 알고 있는 클래스의 인스턴스가 참조형인데, new 키워드와 생성자 호출을 사용해서 생성한다. 생성자는 인자가 없으면 디폴트 값으로 인스턴스의 변수들을 초기화한다. 여기서 디폴트 값은 다른 설정이 없으면 null 이다. (메모리의 무엇도 가리키고 있지 않다는 뜻이다)
  • C와 다르게 자바에 포인터가 없는 이유는 원시 타입과 참조형 타입을 거의 유사하게 사용할 수 있도록 자바가 메모리를 관리해주기 때문이다. 메모리를 신경쓰지 않고도 객체에 대해 참조할 수 있는 것이다.
  • 인터페이스는 참조형이지만 초기화할 때 자기 자신의 생성자가 아닌 구현체의 생성자를 사용해야 한다.
  • 즉, 참조형 타입은 추상화되어 있는 클래스를 참조함으로서 인스턴스를 통해 구체화하는 타입이다.

배열 생성 방법 & 주의할 점

원시 타입과 참조형 타입의 배열은 그 선언과 초기화에서 다른 양상을 보인다.

우선, 대표적인 원시 타입의 배열인 정수 배열을 초기화할 때를 생각해보자.

int[] intArray = new int[10]; // {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

위 코드는 사이즈 10의 정수 배열을 생성하고 0으로 초기화한다.

위에서 설명했듯이 int 는 선언만 했을 시 초기값을 0으로 갖기 때문이다.

그래서 아래와 같은 동작이 가능하다.

intArray[3] = 13;

intArray[3] 은 0으로 초기화되어 있기 때문에 위와 같이 값을 할당하면 값이 바뀌기만 하면 되어서 아무 문제가 없다.

 

하지만 참조형 타입의 배열을 생성하고 싶을 때는 어떨까?

참고한 사이트에서는 Queue 타입의 배열을 생성하는 방법을 설명하고 있다.

우선 Queue 를 선언할 때를 생각해보자.

Queue<Integer> queue = new LinkedList<>();

위와 같이 new 키워드를 사용하고, 생성된 객체에는 null 이 할당되어 있다.

그렇다면 아래는 어떨까?

Queue<Integer>[] queueArray = new Queue<>[10];

원시 타입 때와 마찬가지로 길이 10의 배열을 생성하지만, 이번에는 참조형 타입 Queue 가 선언만 되고 초기화된 적이 없기 때문에 null 10개의 배열이 만들어진다. 그래서 아래와 같은 동작은 NullPointerException 을 발생시킨다.

queueArray[3].add(13);

 

위와 같이 사용했을 때 결과

 

queueArray[3] 에 Queue 자료형이 존재해서 .add() 메서드로 값을 추가할 수 있을거라 생각했는데,

배열 생성만 해서는 10개의 Queue 가 만들어지진 않는 것이다.

 

그래서 아래와 같이 배열 생성 후 한 번 더 초기화해야 한다.

Queue<Integer> queueArray = new Queue<>[];

for (int i = 0; i < queueArray.length; i++) {
    queueArray[i] = new LinkedList<>();
}

배열 내를 10개의 큐로 채워주었다.

 

기수 정렬이 올바르게 동작했다.

결론

 

결론적으로, 참조형 타입의 배열 생성을 쉽게 생각하면 다음과 같다:

 

배열 생성 자체는 빈 틀을 만드는 과정이고, 직접 채우는 것은 반복문을 통해 해결해야 한다.

 

출처

https://stackoverflow.com/questions/8346052/create-an-array-of-queues-in-java

 

Create an array of Queues in Java

I'm writing my own PriorityQueue class and I have: private Queue<E>[] queues; public PriorityQueue(int maxSize) { queues = new Queue[maxSize+1]; size = maxSize; } This compiles, but w...

stackoverflow.com

 

'Java' 카테고리의 다른 글

DTO 의 Deserialize(역직렬화): 3부  (0) 2022.11.30
DTO 의 Deserialize(역직렬화): 2부  (0) 2022.11.30
DTO 의 Deserialize(역직렬화): 1부  (0) 2022.11.29
[Java] enum type Class  (0) 2022.11.18
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함