코딩 이야기

JAVA 참조 타입과 참조 변수 본문

JAVA

JAVA 참조 타입과 참조 변수

별메아리 2023. 2. 1. 10:41
728x90

기본 타입과 참조 타입

기본 타입으로 선언된 변수와 참조 타입으로 선언된 변수의 차이점은 저장되는 값입니다. 기본 타입인 byte,char,short,int,long,float,double,boolean 변수는 실제 값을 변수 안에 저장하지만, 참조 타입인 배열,열거,클래스,인터페이스 변수는 메모리의 번지르 변수 안에 저장합니다. 번지를 통해 객체를 참조한다는 뜻에서 참조 타입이라고 부릅니다.

참조 타입

메모리 사용 영역

1. 메소드 영역

메소드 영역에는 코드에서 사용되는 클래스들을 클래스 로도로 읽어 클래스 별로 런타임 상수 풀, 필드 / 메소드 데이터, 메소드 코드, 생성자 코드 등을 분류해서 저장합니다. 메소드 영역은 JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역입니다.

 

 

2. 힙 영역

힙 영역은 객체와 배열이 생성되는 영역입니다. 힙 영역에 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조한다. 참조하는 변수나 필드가 없다면 의미 없는 객체가 되기 때문에 이것을 쓰레기로 취급하고 JVM은 Garbage Collector를 실행시켜 스레기 객체를 힙 영역에서 자동으로 제거합니다. 그렇기 때문에 개발자는 객체를 제거하기 위해 별도의 코드를 작성할 필요가 없습니다. 사실 Java는 고드로 객체를 직접 제거시키는 방법을 제공하지 않습니다. 다만 System.gc()라는 메소드가 있지만 이는 직접적으로 쓰레기를 제거한다기 보다는 JVM에게 제거를 요청하는 형태입니다. 이러한 Garbage Collector의 존재가 C언어와의 차이점 중 하나입니다. C언어에서 참조 변수(포인터)를 사용하게되면 직접 쓰레기를 제거해줘야 하기 때문입니다.

 

3) JVM(Java Virtual Machine) Stack Area

JVM 스택 영역은 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당됩니다. 자바 프로그램에서 추가적으로 스레드를 생성하지 않는다면 main 스레드만 존재하므로 JVM 스택도 하나입니다. 이때 스레드의 개념은 어려운 개념이여서 나중에 따로 작성하여 설명하겠습니다. JVM 스택은 메소드를 호출할 때마다 프레임을 추가하고 메소드가 종료되면 해당 프레임을 제거하는 동작을 수행합니다. 

 

프레임 내부에는 로컬 변수 스택이 있는데 기본 타입 변수와 참조 타입 변수가 추가되거나 제거됩니다. 변수는 선언된 블록 안에서만 스택으로 존재하고 블록을 벗어나면 스텍에서 제거됩니다. 이는 메소드, if문, for문 등에서 내부에서 생성된 변수는 해당 로컬 변수 스택에만 존재하여 해당 구문을 빠져 나오게되면 제거가 되여 외부에서는 사용이 불가능 하다는 것을 말합니다. 다만 배열 같은 경우에는 배열의 변수는 스택 영역에 생성되지만 배열의 데이터 자체는 Heap 영역에 생성되어 제거되지 않습니다. 즉 Java에서 배열은 객체로 취급을 합니다. 

 

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

기본 타입 변수의 --, != 연산은 변수의 값이 같은지, 아닌지를 조사하지만 참조 타입 변수들 간의 ==, != 연산은 동일한 객체를 참조하는지, 다른 객체를 참조하는지 알아볼때 사용한다. 참조 타입 변수의 값은 힙 영역의 객체 주소 이므로 --, != 연산은 객체으 ㅣ번지값을 비교한다 동일한 번지 값을 갖고 있다는 것은 동일한 객체를 참조한다는 의미한다.

 

null과 NullPointException

참조 타입 변수는 힙 영역의 객체를 참조하지 않는다는 뜻으로 null(널) 값을 가질 수 있습니다. null 값도 초기값을 사용가능하기 때문에 null로 초기화된 변수는 스택영역에 생성된다

 

 

 

 

String 타입

일반적으로 변수에 문자열을 저장할 겨웅에는 문자열 리터널을 사용하지만,

new 연산자를 사용해서 직접 String 객체를 생성시킬 수도 있습니다. new 연산자는 힙 영역에 새로운 객체를 만들 때 사용하는 연산자로 객체 생성 연산자라고 합니다.

String name1 = new String("신용권");

String name2 = new String("신용권");

이 경우 name1 와 name2 는 서로 다른 string 객체를 참조하고 있습니다.

 

문자열 리터널로 생성하느냐 new 연산자로 생성하느냐에 따라 비교 연산자의 결과는 달라질 수 있습니다.

 

null과 NullPointerExemption

참조 타입 변수는 힙 영역의 객체를 참조하지 않는다는 뜻으로 null(널)값을 가질 수 있습니다. null 값도 초기값을 사용할 수 있기 때문에 null로 초기화된 참조 변수는 스택 영역에 생성됩니다.

참초 타입 변수가 null 값을 가지는지 확인하려면 ==,!=연산을 수행하면됩니다.

 

문자열 비교

package ch02;

public class StringEqualsExample {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String strVar1 = "신민철";
		String strVar2 = "신민철";
		
		if (strVar1 == strVar2) {
			System.out.println("strVal과 strVar2는 참조가 같음"); 
			} else {
			System.out.println("strVal1과 strVal2는 참조가 다름");
			}
			
			if (strVar1.equals(strVar2)) {
				System.out.println("strVar1과 strVal2는 문자열이 같음");
			}
			
			String strVar3 =new String("신민철");
			String strVar4 =new String("신민철");
			
			if(strVar3 == strVar4 ) {
				System.out.println("strVar3과 strVar4는 참조가 같음");
			} else {
				System.out.println("strVar3과 strVar4는 참조가 다름");
			}
			
			if (strVar3.equals(strVar4)) {
				System.out.println("strVar3과 strVal4는 문자열이 같음");
			}
		}
		
	}

 

728x90

'JAVA' 카테고리의 다른 글

자바 배열 (5일)  (0) 2023.02.02
자바 배열 (4일)  (0) 2023.02.01
JAVA 4일  (0) 2023.02.01
JAVA 3일차수업  (0) 2023.01.31
자바 2일차  (0) 2023.01.30
Comments