Java/혼공자

Chapter 05 참조 타입

yeooniyeoon 2022. 12. 29. 17:58
728x90
SMALL

기본 타입 변수와 참조 타입 변수

자바의 데이터 타입은 크게 기본 타입과 참조 타입으로 나뉜다.

기본 타입은 정수, 실수, 논리 타입으로 나뉘고

참조 타입은 배열, 열거, 클래스, 인터페이스 타입이 있다.

 

자바에서 모든 변수는 스택 영역에 생성되지만

기본 타입 변수 -> 변수에 값을 직접 저장하고,

참조 타입 변수 -> 힙 영역에 생성된 객체의 번지를 저장한다.

 

따라서 참조 변수는 번지를 참조하여 객체에 접근하므로 참조 타입 변수라고 한다.

 

 

메모리 사용 영역

메모리 영역은 메소드 영역, 힙 영역, jvm 스택 영역으로 나뉜다.

 

메소드 영역에는 .java 파일 작성 후 컴파일을 통해 생성된 바이트 코드 파일을 실행하면 메소드 영역에 로딩이 된다.

클래스의 바이트 코드들이 메소드 영역에 저장된다.

 

 

힙 영역에는 클래스로부터 생성된 객체들이 저장된다.

 

 

jvm 스택 영역에는 메소드가 호출될 때마다 프레임이라는 것이 추가가 되는데

프레임 안에는 메소드 실행 시 생성된 변수들이 저장된다.

메소드가 종료되면 프레임도 같이 제거된다.

 

프레임 안의 변수도 스택 형태로 저장되는데 이때 참조 타입 변수가 사용된 경우,

변수이므로 스택 영역에 생성되지만 그 안의 값은 힙 영역에 생성된 객체의 주소가 저장된다.

 

 

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

기본 타입 변수의 ==, != 비교 연산 => 값 비교 시 사용하지만

참조 타입 변수의 ==, != 비교 연산 => 번지 비교 시 사용된다.

 

번지가 같다는 것은 동일한 객체를 참조하고 있다는 것으로도 해석할 수 있다.

String str1 = "hi";
String str2 = "hello";
System.out.println(str1 == str2);

str1과 str2는 다른 객체를 참조하고 있으므로

위 코드의 실행 결과는 false가 출력된다.

 

 

null과 NullPointerException

자바에선 error와 exception이란 용어를 구분하여 사용한다.

error => 하드웨어, OS 문제 발생 시 사용

exception => 프로그램 실행 도중 문제 발생 시 사용

 

참조 타입 변수는 객체를 참조하지 않는다는 의미로 null값을 가질 수 있다.

참조 변수가 null 값을 가진 경우에 해당 변수를 통해 존재하지 않는 객체의 데이터나 메소드를 사용하는 경우

NullPointerException 예외가 발생하게 된다.

예외를 처리하기 위해선 참조 변수가 객체를 참조하도록 해줘야 한다! ! !

 

 

String 타입

String 변수에 문자열 리터럴 대입 시

힙 영역에 String 객체가 생성되고

스택 영역에 생성된 변수는 객체를 참조하게 된다.

 

자바는 문자열 리터럴이 동일한 경우 동일한 String 객체를 공유하게 된다.

String str1 = "yeoon";
String str2 = "yeoon";

System.out.println(str1==str2);

위 코드의 str1과 str2는 동일한 문자열 리터럴 값을 갖고 있으므로 동일한 String 객체를 공유하고 있다.

따라서 str1 == str2의 결과는 true이다.

 

 

new 연산자

new 연산자는 객체 생성 연산자로 힙 영역에 새로운 객체를 생성할 때 사용한다.

new 연산자를 사용해 동일한 문자열 리터럴 저장할 경우에는 객체를 공유하지 않는다.

new 연산자로 String 객체를 별도로 생성했기 때문에 서로 다른 객체를 참조하게 되는 것이다.

String str1 = "yeoon";
String str2 = new String("yeoon");

System.out.println(str1 == str2);

위 코드의 str1과 str2는 동일한 문자열 리터럴을 갖지만 참조하는 객체는 다르다.

str2에 문자열 저장 시 new 연산자를 사용했기 때문에 이미 생성된 객체를 공유하는 것이 아닌

새로운 객체를 생성한 뒤 그 객체를 참조하기 때문이다.

 

 

문자열 비교 시에는 ==, != 비교 연산자가 아닌 equals() 메소드를 사용해야 한다.

참조 변수끼리 비교 연산 수행 시 번지를 비교하지만

equals() 메소드는 번지가 아닌 원본 문자열과 매개값으로 주어진 문자열의 내용이 동일한지를 비교하기 때문이다.

 

 

객체를 참조하던 변수에 다른 값을 대입할 경우 원래 참조되던 객체는 참조를 잃게 된다.

String name = "yeoon";
name = null;

위와 같은 경우 힙 영역에 생성된 String 객체는 참조를 잃게 되는 것이다.

참조를 잃은 String 객체는 쓰레기 객체로 취급되어 JVM에서 쓰레기 수집기를 구동시켜 자동 제거된다.

 

 

배열

배열은 같은 타입의 데이터를 연속된 메모리 공간에 할당하고 각 데이터에 인덱스를 부여해놓은 자료구조이다.

 

배열은 두가지 특징을 갖고 있다.

1. 같은 타입의 데이터만 저장할 수 있고

2. 한번 생성한 뒤 배열 길이를 수정할 수 없다.

 

 

배열 선언

배열을 선언하는 방법은 두가지가 있다.

 

1. 타입[] 변수명;

2. 타입 변수명[];

 

 

배열 생성

배열을 생성하려면 값 목록으로 생성하는 방법과 new 연산자를 사용하는 방법이 있다.

 

값 목록으로 배열을 생성하는 방법은 배열 선언과 동시에 값을 주는 것이다.

이때 주의할 점은 배열 변수를 이미 생성한 뒤 다른 실행문에서 중괄호를 사용한 배열을 생성할 수 없다.

이런 경우 new 연산자를 사용하여 배열을 생성하여야 한다.

 

값 목록은 없지만 배열을 미리 생성할 경우 new 연산자를 사용하는데

new 연산자로 배열을 생성할 경우 배열은 자동으로 기본값으로 초기화된다.

 

 

배열 길이

배열 길이란 배열에 저장할 수 있는 전체 항목을 의미한다.

배열 길이를 구하려면 배열 객체의 length 필드를 읽으면 된다.

읽는 방법은 배열 변수에 도트 연산자르 붙이고 length를 붙여주면 된다.

arr1.length;

length 필드는 읽기 전용 필드이기 때문에 값을 변경할 수 없다.

 

 

다차원 배열

자바에서 다차원 배열은 1차원 배열이 서로 연결된 구조로 표현된다.

예를 들어 길이가 2행 3열인 int형 배열 scores가 있다고 하면

scores는 길이가 2인 배열 A를 참조한다.

배열 A의 scores[0]은 다시 길이가 3인 배열 B를 참조한다.

그리고 배열 A의 scores[1]은 길이가 3인 배열 C를 참조하게 된다.

 

 

객체를 참조하는 배열

참조타입 배열은 각 항목에 값을 직접 저장하지 않고 객체의 번지를 갖고 있다.

예를 들어 String 배열은 String 객체의 번지를 갖고 있는데 이는 String 배열은 String 객체를 참조하는 것이라 볼 수 있다.

그렇기 때문에 String 배열의 각 항목은 String 객체와 동일하게 취급해야 한다.

 

 

배열 복사

배열을 복사하는 두가지 방법이 있다.

1. for문을 사용하여 하나씩 일일히 복사하는 방법

 

2. System.arraycopy() 메소드를 사용하는 방법

System.arraycopy(원본 배열, 시작 인덱스, 복사할 배열, 시작 인덱스, 길이);

System.arraycopy() 메소드 사용시 복사되지 않은 항목은 기본값으로 초기화된다.

 

 

향상된 for문

향상된 for문에선 루프 카운터 변수와 증감식을 사용하지 않는다.

배열에서 꺼낸 항목을 저장할 변수, 콜론, 배열을 나란히 작성한다.

for(항목 저장할 변수 : 배열) { }

향상된 for문은 배열 항목 개수만큼 반복 후 자동적으로 for문을 빠져나간다.

 

 

열거 타입

열거 타입이란 한정된 값인 열거 상수 중 하나의 상수를 저장하는 타입을 말한다.

 

 

열거 타입 선언

열거 타입 이름을 정한 후 해당 이름으로 소스파일을 생성한다.

열거 타입 명은 첫글자를 대문자로 하는 것이 관례이며 (열거타입명과 소스파일명은 대소문자까지 일치해야 함)

열거상수는 모두 대문자로 작성해야 한다.

public enum Week { MONDAY; TUESDAY; WEDNESDAY; THURSDAY; FRIDAY; SATURDAY; SUNDAY; }

 

 

열거 타입 변수

열거 타입도 타입이므로 변수를 선언하고 사용해야한다.

열거상수는 단독으로 사용할 수 없으며

도트 연산자를 사용하여 열거타입.열거상수 형태로 사용할 수 있다.

 

열거타입도 참조타입이므로 열거 타입 변수에 null값을 저장할 수 있다.

 

열거 상수도 참조타입이므로 열거 객체로 생성된다.

열거 상수들은 힙 영역에 해당 열거타입 객체로 생성된 뒤

메소드 영역에 생성된 열거 상수가 해당 객체를 참조하게 된다.

 

열거 타입 변수에 저장되는 값은 열거 상수가 참조하는 객체의 번지이다.

따라서 열거 타입 변수와 열거 상수는 동일 객체를 참조하게 되며 == 비교 연산 시에도 true를 반환하게 된다.

728x90
반응형
SMALL

'Java > 혼공자' 카테고리의 다른 글

Chapter 07 상속  (0) 2023.01.16
[혼공학습단 9기] 혼공자 2주차  (0) 2023.01.15
Chapter 06 클래스  (0) 2023.01.10
[혼공학습단 9기] 혼공자 1주차  (0) 2023.01.08
Chapter 01 자바 시작하기 ~ 04 조건문과 반복문  (0) 2022.12.28