본문 바로가기

JAVA,JSP

동일성, 동등성

두 변수의 값을 비교하기 위해, 우리는 == 연산자를 사용했습니다.

하지만 이 연산자를 이용한 비교는, primitive(원시) 타입의 자료형에만 해당하는 사항입니다.

( primitive 타입 자료형이란 int, double, char, boolean 등의 기본 자료형을 말합니다.)

하지만 자바에서 지원하는 타입은 primitive 타입만이 있는 것이 아닙니다.

우리가 흔히 사용하는 오브젝트. 주소값을 가지는 reference 타입이라는 자료형도 존재합니다.


reference 타입이란 우리가 흔히 사용하는, new 연산자로 생성할 수 있는 오브젝트를 말합니다

new 연산자란 간단히 클래스의 오브젝트를 생성하는 연산자라고 표현할 수 있지만,

좀 더 상세하게 얘기하면 클래스의 오브젝트를 생성하여 메모리에 올리고, 그 참조변수를 반환해주는 연산자입니다.

primitive 타입과의 차이점이 여기서 발생하는 것입니다. 바로 참조변수 라는 개념이죠.

참조변수란 다들 아시겠지만, 주소값을 의미합니다. 메모리에 올라간 오브젝트를 가리키는 주소값이죠.

이러한 reference 타입 자료형을 비교할 때는 primitive 타입 변수와는 달리, 값의 비교가 두 가지의 의미를 가지게 됩니다.


바로 동일성과 동등성의 개념입니다.

동일하다 는 두 개의 오브젝트가 완전히 같을 경우를 의미하고,

동등하다 는 두 오브젝트가 같은 정보를 같고 있을 경우를 의미합니다.

동일하다 의 경우 == 연산자로 표시되고, 동등하다 의 경우 equals 연산자로 표시됩니다.

오브젝트 간 == 연산자는 주소값의 비교, equals는 내용의 비교가 됩니다.

== 연산자가 성립한다는건 주소값이 같다는 뜻이고, 결국 두 변수가 같은 오브젝트를 가리키고 있다는 의미이죠.


예를 하나 들어보겠습니다.

String st1 = new String("aaa");
String st2 = new String("aaa");

System.out.println(st1==st2);
System.out.println(st1.equals(st2));

st1과 st2는 각각 new 연산자를 사용함으로써 새로운 오브젝트 메모리에 생성됬고, 그 참조변수가 반환되어 저장되있습니다.

두 주소를 가져와 비교를 하니 당연히 동일하지 않습니다. false가 출력됩니다. 두 오브젝트는 다른것이죠.


equals의 경우 String 클래스에서 오버라이딩 해서 만든건데, 주소가 아닌 변수 내 값 비교를 해줍니다.

aaa와 aaa는 같은 문자열이므로 true가 출력됨을 볼 수 있습니다.


※ String의 특이한 점

String은 primitive 타입이 아닌 reference 타입이지만, 자바에서 조금 특별히 대우해 주고 있습니다.

위의 예제에서 String을 기본적인 reference 타입의 변수를 생성하듯 new 연산자를 사용했지만, 

다른 방식의 변수 초기화도 존재합니다. 대부분이 이 방법을 사용하죠.


String st = "aaa";


이렇게 일반 primitive 타입 변수 선언하듯 변수를 선언할 수 있게 문법적으로 허락하고 있습니다.

그리고 실제로 값을 비교해보면 primitive 타입 변수와 같은 비교가 가능하다는 걸 보실 수 있습니다.

String st1 = "aaa";
String st2 = "aaa";

System.out.println(st1==st2);

결과는 true가 나옵니다.

자바에서는 위 처럼 문자열 상수에 대해서 문자열이 동일할 경우 하나의 인스턴스만 생성하고, 이를 공유하도록 합니다.

"aaa"라는 문자열이 메모리에 생성되면서 st1에 주소값을 넘겨주었고,

st2를 생성하는데 이미 생성된 "aaa" 문자열과 똑같으므로 새로 메모리에 생성하지 않고 기존에 생성된

"aaa" 문자열의 주소를 돌려줘서 공유하게 하는 것입니다!


왜 String만 이런식으로 특별 대우를 하는걸까요

그것은 문자열 이라는 특성 때문입니다.

인스턴스의 생성이란 사실 시스템에 부담이 되는 요소입니다. 

그런데 문자열을 표현할 때 마다 인스턴스가 생성되니, 이를 줄일 필요가 있었던 것입니다.


이러한 문자열의 공유는 자바 뿐만 아니라 오늘날 대부분의 프로그래밍 언어가 갖추고 있는 특징입니다.


도움이 되셨기를.. 감사합니다.

'JAVA,JSP' 카테고리의 다른 글

예외처리(1)  (0) 2016.06.30
java.lang.NoSuchMethodError  (1) 2016.06.28
Jad 설치 및 이클립스에 추가하기  (0) 2016.06.13
System.out 출력 포맷  (0) 2016.06.10
String 클래스 matches 메서드  (0) 2015.09.20