1. 배열의 복사

리스트와 다르게 배열은 처음 초기화된 크기를 변경 할 수 없다는 단점을 갖고있습니다.

때문에 기존에 존재했던 배열의 크기가 작아 추가 공간이 필요하게 된다면, 기존보다 큰 배열을 생성하고 거기에 기존에 데이터를 복사해 넣어줘야 할 필요가 있습니다.

 

이를위해 단순히 반복문을 활용하여 하나씩 데이터를 넣어줄 수도 있지만, 상당히 귀찮은 일이 아닐 수 없습니다.

 

이를 쉽게 해주는 함수가 존재합니다.

 

System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

// Ststem.arraycopy( 배열 A, 복사 시작점, 배열 B, 붙여넣을 시작점, 복사할 길이 );

// 배열A를 배열B에 복사

 

실행결과

 

위의 코드를 보게되면 arr1을 arr2의 1번 index부터 복사한것을 볼 수 있습니다.

 

1. Java에서 비교연산자

프로그래밍 언어에서 자주 사용되는 '=='과 '!='이라는 두 연산자는 두 변수가 동일한 값을 갖고있는지 파악하는 용도로 많이 사용됩니다.

 

특히 조건문에서 많이 사용되죠.

 

가볍게 사용하고 있지만, Java에서 이 연산자들은 단순히 동일한 값을 확인하는 용도로 사용되지 않습니다.

 

왜냐하면, 이 연산자의 양옆에 오는 값이 동일한 것인지를 확인하는 것이 아닌, 양옆에 오는 두 객체가 동일한 참조를 하는지 확인하는 용도로 사용되기 때문입니다.

 

 

앞서 JVM가 메모리 영역을 어떻게 관리하는지 생각하며 진행해보겠습니다.

 

JVM Stack 영역에 저장되어있는 '참조 변수'는 아래와 같은 구조로 저장되어있습니다.

 

var1 Heap 3번
var2 Heap 8번
var3 Heap 11번

 

각각의 '참조 변수'는 힙 영역의 특정 위치를 가리키고있고, 이를통해 힙영역에 저장되어있는 실제 데이터에 접근하게됩니다.

 

만약 Heap영역 3번과 8번이 동일한 값을 갖고있다면, var1 == var2라고 했을 때 어떤 값을 반환받을까요?

 

정답은 'False'입니다.

 

힙 영역에는 둘 다 같은 값은 갖고있다해도 참조하는 Heap영역의 주소가 다르기 때문에 False라는 값을 반환하게됩니다.

 

 

 

2. 객체의 생성

위와같이 Java라는 녀석에서 '참조변수'는 참조하는 힙영역이 어디냐에 따라 True나 False를 반환하지만, 실제 코드를 사용할 때에는 가끔 이러한 것들이 이해가 안되는 경우를 볼 수 있습니다.

 

 

만약 아래와 같은 코드를 수행했다고 생각해봅시다.

 

String user1 = "YoungQ";

 

위의 코드를 수행하면 Heap영역 어딘가에 "YoungQ"라는 데이터를 갖고있는 객체가 생성될 것입니다. 여기서는 그곳을 Heap 1번이라고 가정하겠습니다.

 

Heap1 : "YoungQ"

 

위와같이 Heap영역에 1번에 "YoungQ"라는 값이 들어간다면, user1은 Heap1을 참조하게 될 것입니다. 그럼 전체적으로 보면 아래와 같은 형태가 됩니다

 

Stack 영역 Heap 영역
user1 : Heap1 Heap1 : "YoungQ"

 

 

그럼 여기서 아래와 같은 코드를 수행하면 어떻게 될까요?

 

String user2 = "YoungQ";

 

user1과 마찬가지로 새로운 Heap2 영역에 "YoungQ"라는 데이터가 들어갈 것이라고 생각되지만, 그렇게되면 동일한 데이터를 위해 여러 메모리를 할당하는 형태가되기 때문에, 메모리 낭비가 문제가 발생하여 Java에서는 다르게 이를 처리합니다.

 

방식은 간단합니다. 동일한 데이터가 이미 Heap영역에 존재한다면, 그곳을 참조하도록만 만들어주면 되는것이죠.

 

메모리상에는 아래와 같이 들어갑니다.

 

Stack 영역 Heap 영역

user1 : Heap1

user2 : Heap1

Heap1 : "YoungQ"

 

일반적으로 이러한 동시참조의 문제는 user1의 데이터를 변경했을 때, user2의 데이터도 변경되는 문제가 발생한다는 것입니다.

 

그렇게되면 정말 큰 문제가 되죠.

 

하지만, 걱정하지마세요. 하나의 데이터를 변경하게되면, 변경된 데이터로 새로운 객체를 만들어 참조할 힙영역의 주소를 알아서 변경해주니까요.

 

더보기

참고로 원하는 경우 새로운 객체를 만드는 방법도 존재합니다.

 

String user1 = "YoungQ";

String user2 = new String("YoungQ");

 

이와같이 코드를 작성하면 힙 영역에 두 개의 "YoungQ"라는 데이터를 갖은 객체가 생성됩니다.

 

실행결과

 

 

3. NULL 참조

값이 존재하지 않는 경우를 흔히 null로 표시하는 경우가 많이 있습니다.

 

참조변수도 이러한 null값을 갖을 수 있습니다.

 

String user3 = null;

 

위의 코드에서 user3라는 변수는 존재하지만, user3는 어떠한 영역도 참조하지 않는 변수를 의미합니다.

 

이러한 null은 Java 뿐만아니라 다양한 곳에서 사용됩니다. 하지만, 유독 Java에서 null이라는 녀석 문제가 되는데 그 이유는 Java가 대표적인 객체지향 언어이기 때문이죠.

 

많은 것들이 객체 단위로 이뤄지기 때문에 툭하면 NPE(Null Pointer Exception)이라는 애러를 발생시킵니다.

 

Null 값을 참조하려하면 발생하는 녀석이죠.

 

 

실행결과

 

위와같이 말이죠.

+ Recent posts