JavaStudy

참조타입

핑구뱅구 2021. 5. 6. 15:34

1. 데이터 타입

 

크게 기본 타입(primitive type)참조 타입(reference type)로 분류된다.

 

- 기본 타입 ( 실제 값을 변수안에 저장 )

* 정수 타입 : byte, char, short, int, long

* 실수 타입 : float, double

* 논리 타입 : boolean

 

- 참조 타입 ( 메모리의 번지를 변수 안에 저장 : 번지를 통해 객체를 참조한다. )

* 배열 타입, 열거 타입, 클래스, 인터페이스

 

- ( JVM이 운영체제에서 할당받은 ) 메모리 사용 영역 (Runtime Data Area)

1) 메소드 영역

JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역

클래스(~.class)들을 클래스 로더로 읽어 클래스별로 정적필드(static field)와 상수(constant), 메소드 코드, 생성자(constructor) 코드 등을 분류해서 저장

 

2) 힙 영역

객체와 배열이 생성되는 영역

여기에 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조

 

3) (JVM)스택 영역

기본 타입 변수는 스택 영역에 직접 값을 가지고 있지만,

참조 타입 변수는 스택 영역에 힙 영역의 객체 주소를 가진다.

ex) int[] scores = {10,20,30};

    배열 변수 scores는 스택 영역에 생기고, 실제 10,20,30을 갖는 배열은 힙 영역에 생성

 

- 메소드를 호출 할 때마다 프레임(frame)을 추가(push)하고

  메소드가 종료되면 해당 프레임을 제거(pop)을 하는 동작을 수행

- 프레임 내부에는 로컬 변수 스택(기본 타입 변수와 참조 타입 변수가 추가 or 제거되는)이 있음. 

 

2. 참조 변수의 ==, != 연산

기본 타입 변수 ==, !=  : 변수의 값이 같은지, 아닌지 조사

참조 타입 변수 ==, != : 동일한 객체를 참조하는지, 다른 객체를 참조하는지 조사

                              : 참조 타입 변수의 값 -> 힙 영역의 객체 주소 -> 결국 주소 값을 비교하는 것

                                ->  동일한 주소 값을 갖고 있다는 것 == 동일한 객체를 참조한다는 의미

 

3. null과 NullPointerException

 

1) null

참조 타입 변수는 힙 영역의 객체를 참조하지 않는다는 뜻으로 null 값을 가질 수 있다.

null 값도 초기값으로 사용할 수 있기 때문에 null로 초기화된 참조 변수는 스택 영역에 생성된다.

 

2) NullPointerException

참조 변수가 null을 가지고 있을 경우 -> 참조 객체가 없으므로 변수를 통해 객체를 사용 할 수 없다.

만약, null상태에서 있지도 않은 객체의 데이터(필드)나 메소드를 사용하는 코드를 실행하면 NullPointerException 발생

 

4. String 타입

 

◆  자바는 문자열을 String 변수에 저장

 

1) String 변수 선언 -> String 변수;

2) 큰따옴표로 감싼 문자열 리터럴을 대입 -> 변수 = "문자열";

1,2) 변수 선언과 동시에 문자열 저장  -> String 변수 = "문자열";

 

ex) String name;

     name = "핑구";

     String study = "자바";

-> name변수와 study 변수는 스택 영역에 생성, 문자열 리터럴인 "핑구"와 "자바"는 힙 영역에 String 객체로 생성

    name변수 study 변수에는 String 객체의 주소 값이 저장

 

 자바는 문자열 리터럴이 동일하다면 String 객체를 공유하도록 되어 있음. -> 동일한 객체를 참조한다는 뜻.

ex) String name1 = "핑구";

     String name2 = "핑구";

-> name1, name2변수에 저장되어 있는 객체의 주소는 동일하다.

 

 new 연산자 : 힙 영역에 새로운 객체를 만들 때 사용하는 연산자로 객체 생성 연산자라 한다.

ex) String name1 = new String("핑구");

     String name2 = new String("핑구");

-> name1변수와 name2변수는 서로 다른 String 객체를 참조하고 있다.

   = name1변수와 name2변수는 서로 다른 객체의 주소를 가지고 있다.

 

String 객체를 문자열 리터럴로 생성하느냐 new 연산자로 생성하느냐에 따라 비교 연산자의 결과는 달라 질 수 있다.

  ### 왜? == 연산자는 변수에 저장된 객체의 주소가 동일한지를 검사하는 것이기 때문에

 

- 동일한 String 객체이건 다른 String객체이건 상관없이 내부 문자열을 비교하고 싶을 때

 : String 객체의 equals() 메소드를 사용

 * equals() 메소드란?

   원본 문자열과 매개값으로 주어진 비교 문자열이 동일한지 비교한 후 true 또는 false를 리턴한다.

   ex) boolean result = str1.equals(str2);   -> str1 : 원본 문자열,  str2 : 비교 문자열

 

◆ Garbage Collector

JVM은 참조되지 않은 객체를 쓰레기 객체로 취급하고 garbage Collector를 구동시켜 메모리에서 자동 제거한다.