Java
[Java]참조 타입(이것이 자바다 Ch.5)(작성 중)
Woonys
2022. 5. 20. 19:10
반응형
5.1 데이터 타입 분류
- 데이터 타입
- 원시 타입(Primitive type)
- 정수 타입
- byte(1byte)
- char(2byte)
- short(2byte)
- int(4byte)
- long(8byte)
- 실수 타입
- float
- double
- 논리 타입
- boolean
- 정수 타입
- 참조 타입(Reference type)
- 배열 타입(array)
- 열거 타입(enum)
- 클래스(class)
- 인터페이스(Interface)
- 원시 타입(Primitive type)
- 변수: 스택에 생성
- int, double → 직접 값을 저장
- 객체: 힙에 생성
- 클래스 변수 → 힙 영역의 객체 주소 값을 갖는다.
- 주소를 통해 객체를 참조한다는 뜻에서 클래스 변수를
참조 타입(Reference type)
변수라고 한다.
5.2 메모리 사용 영역
JVM이 사용하는 메모리 영역
- java.exe → JVM은 운영체제에서 할당받은 메모리 영역을 아래와 같이 세부 영역으로 구분해서 사용
- 메소드 영역: 클래스 들어가 있음
- 힙 영역: 객체와 배열 들어가 있음
- 스레드(n개)
- JVM 스택이 각 스레드별로 위치
- JVM 스택 내에는 n개의 프레임 위치 → 스택 형태로 push/pop
- JVM 스택이 각 스레드별로 위치
힙 영역
- 객체, 배열 생성되는 영역
- 힙 영역에 생성된 객체, 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조
- 참조하는 변수, 필드가 없다면 의미 없는 객체 → GC 발동! 쓰레기 객체를 힙 영역에서 자동 제거
- 결국 참조하냐 안하냐로 GC가 발동하는 것!
- 개발자는 객체 제거하기 위해 별도 코드 작성할 필요도 없고, 애초에 자바는 코드로 객체 제거하는 방법 제공하지 X
JVM 스택(stack) 영역
- JVM 스택: 각 스레드마다 하나씩 존재 & 스레드 시작될 때 할당된다.
- 자바 프로그램에서 추가적으로 스레드 생성 안하면 main 스레드만 존재 → JVM 스택도 하나.
- 메소드 호출할 때마다 프레임을 추가(push) → 메소드가 종료되면 해당 프레임을 제거(POP)
- 프레임 내부: 로컬 변수 스택
- 기본 타입 / 참조 타입 변수 추가/제거(push/pop).
- 변수가 이 영역에 생성되는 시점: 초기화될 때 → 최초로 변수에 값이 저장될 때
- 변수는 선언된 블록 안에서만 스택에 존재, 블록 벗어나면 스택에서 제거
- 기본 타입 변수: 스택 영역에 직접 값을 갖지만
- 참조 타입 변수: 값이 아니라 힙 영역이나 메소드 영역의 객체 주소를 갖는다.
- 배열 변수 scores: 스택 영역에 생성
- but 실제 10, 20, 30을 갖는 배열은 힙 영역에 생성
- 배열 변수 scores에는 배열의 힙 영역 주소가 저장!
5.3 참조 변수의 ==, != 연산
- 기본 타입 변수의 ==, != ⇒ 변수 값이 같은지 아닌지만 조사
- 참조 타입 변수 간의 ==, != ⇒ 동일 객체를 참조하는지 다른 객체를 참조하는지 비교
- 참조 타입 변수 값 → 힙 영역 내 주소값! 결국 주소 값을 비교하는 것
- 두 참조 변수가 동일한 주소값을 갖는다? → 동일한 객체를 참조한다는 의미
5.4 null과 NullPointerException
- 참조 변수: 힙 영역 객체를 참조하지 않는다는 뜻으로 null 값 갖는다.
- null 역시 초기값으로 사용 가능 → null로 초기화된 참조 변수는 스택 영역에 생성(힙에 생성될 이유 X 애초에 힙에 들어갈 게 없다.)
5.5 String 타입 → 문자열이 클래스구나!
- 자바는 문자열을 String 변수에 저장 → 맨 처음에 String 변수 선언해야 한다.
String 변수;
변수 = "문자열"; // 문자열은 큰 따옴표로 감싼다. 그냥 문자(character)는 작은 따옴표
- 문자열을 String 변수에 저장한다? → 틀린 말!
- 문자열이 직접 변수에 저장되는 게 아니라, 문자열은 String 객체로 생성되고 변수는 String 객체를 참조하는 것!
- 클래스 변수 자체는 스택 영역에 생성 → 변수 이름이 key, 문자열이 들어있는 힙 영역의 주소값을 value로 갖는다 & 문자열 리터럴은 힙 영역에 String 객체로 생성
- 문자열이 직접 변수에 저장되는 게 아니라, 문자열은 String 객체로 생성되고 변수는 String 객체를 참조하는 것!
- 일반적으로 변수에 문자열 저장할 경우 문자열 리터럴 사용하나
new
연산자를 사용해서 직접 String 객체 생성시킬 수도 있음 new
연산자: 객체 연산자 → 힙 영역에 새로운 객체 만들 때 사용하는 연산자// name1과 name2는 다른 String 객체를 참조 String name1 = new String("신용권"); String name2 = new String("신용권")); => 들어있는 문자열("신용권")만 같지 두 문자열이 힙 영역 내 전혀 다른 위치에 배치되어 있다.
- 문자열 리터럴로 생성 vs
new
연산자로 생성 비교- 문자열 생성 →
==
연산 시 true- why? 동일 문자열 리터럴로 생성된 객체를 참조하기 때문
// name1 == name2 String name1 = "신민철"; String name2 = "신민철";
new
연산자로 생성 → false- why? new 연산자로 String 객체를 별도로 생성했기에 둘은 다르다.
// name1 != name2 String name1 = "신민철"; String name2 = new String("신민철");
- 동일한 String 객체건 다른 String 객체건 상관없이 문자열 자체만 비교하고 싶으면 String 객체의
equals()
메소드를 사용해야 한다.
- 문자열 생성 →
5.6 배열 타입
배열이란?
- 사용 방식: 배열 이름 옆에 대괄호 [] 사용
score[인덱스값]
배열 선언
- 배열 선언하려면 배열 변수(배열의 이름)을 선언해야 한다.
- 선언 방식
타입[ ] 변수;
int[] intArray; double[] doubleArray; String[] stringArray;
타입 변수[ ];
int intArray[]; double doubleArray[]; String stringArray[];
- 배열 변수: 참조 변수에 속함.
- 배열 역시 객체이므로 힙 영역에 생성
- 배열 변수는 힙 영역의 배열 객체를 참조
- 참조할 객체 없으면 배열 변수는 null 값으로 초기화 → 스택에 위치
값 목록으로 배열 생성
- 배열 항목에 저장될 값 목록 있으면 간단하게 배열 객체 생성 가능
데이터타입[] 변수 = {값0, 값1, 값2, ...};
// ex
String[] names = {"신용권", "홍길동", "감자바"};
- 주의사항: 배열 변수 이미 선언한 후에는 다른 실행문에서 중괄호 사용한 배열 생성은 허용 X
타입[] 변수; // 여기서 변수만 먼저 선언하고
변수 = {값0, 값1, 값2, ...}; // 여기서 배열 생성하면 컴파일 에러 뜬다!
- 만약 배열 변수를 먼저 생성하고 나중에 값 목록 넣어야 할 상황이라면
new
연산자를 사용해서 값 목록 지정해주면 오케이
String[] names = null; // 변수 선언하고
names = new String[] {값0, 값1, 값2, ...}; // 여기서 new 써서 값 채워넣고
new
연산자로 배열 생성
- 값 목록 갖고 있진 않으나 향후 값 저장할 배열 미리 만들려면?
new
연산자로 배열 객체 생성(위와 달리 애초에 처음부터new
연산자로 배열 객체 생성 타입[] 변수 = new 타입[길이]; 변수 = new 타입[길이];
반응형