군만두의 IT 공부 일지

[스터디4] 01. 참조 타입 본문

프로그래밍/Java

[스터디4] 01. 참조 타입

mandus 2025. 1. 23. 21:06

목차

 

 

 

 

 

  제목: 이것이 자바다

  저자: 신용권, 임경균

  출판사: 한빛미디어

  가격: 38,000원

 

 

많이 쓰이는 JAVA 프로그래밍 기본서

 

 

 

 

 

 

 

 

CS 스터디를 진행하고, 같은 스터디원과 자바 스터디를 진행하기로 했습니다. 블로그에 학습 내용을 정리한 후, 배운 내용을 github에 다시 정리하여 팀원들에게 설명하는 방식으로 할 것 같습니다.

 

이 책은 전공 교재로 쓰여도 될 정도로 이미지와 설명이 잘 구성되어 있습니다. 유튜브 강의도 제공하고 있어 도움이 될 것 같습니다. 저와 스터디원 둘 다 전공자이므로 5장부터 학습할 예정입니다. 이번 파트에서는 참조 타입에 대해서 평소 헷갈렸던 내용을 정확히 알고 갈 수 있을 것 같습니다.

5장. 참조 타입

5.1 데이터 타입 분류

  • 자바의 데이터 타입은 기본 타입(primitive type)와 참조 타입(reference type)로 분류됨.

▲ 데이터 타입

  • 기본 타입: 데이터의 실제 값을 저장함. 정수, 실수, 논리값을 저장할 수 있음.
    • 책에서는 문자형 char를 정수형에 포함시킴. char 타입이 내부적으로 정수 값을 사용하여 문자를 표현하기 때문인 것 같음.
값의 분류 기본 타입
정수 byte, char, short, int, long
실수 float, double
논리(true/false) boolean
  • 참조 타입: 객체(object)의 번지를 참조하는 타입. 배열, 열거, 클래스, 인터페이스 타입이 있음.

*객체: 데이터와 메소드로 구성된 덩어리

  • 기본 타입으로 선언된 변수와 참조 타입으로 선언된 변수의 차이점: 저장되는 값
    • 기본 타입으로 선언된 변수: 값 자체를 저장함.
    • 참조 타입으로 선언된 변수: 객체가 생선된 메모리 번지를 저장함.
// 기본 타입 변수
int age = 25;
double price = 100.5;

// 참조 타입 변수
String name = "신용권";
String hobby = "독서";
  • 변수는 모두 스택(stack)에 생성됨.
    • 기본 타입 변수(age, price)는 직접 값을 저장하고 있음.
    • 참조 타입 변수(name, hobby)는 힙 메모리 영역의 String 객체 번지를 저장하고 이 번지를 통해 String 객체를 참조함.

5.2 메모리 사용 영역

▲ 메모리 영역

  • 메모리 영역(Runtime Data Area)
    • 메소드(Method) 영역: 바이트코드 파일을 읽은 내용이 저장되는 영역.
      • 클래스별로 상수, 정적 필드, 메소드 코드, 생성자 코드 등이 저장됨.
    • 힙(Heap) 영역: 객체가 생성되는 영역.
      • 객체의 번지는 메소드 영역과 스택 영역의 상수와 변수에서 참조할 수 있음.
    • 스택(Stack) 영역: 메소드를 호출할 때마다 생성되는 프레임(Frame)이 저장되는 영역.
      • 메소드의 호출이 끝나면 프레임은 자동 제거됨.
      • 프로임 내부에는 로컬 변수 스택이 있음. 이곳에서 기본 타입 변수와 참조 타입 변수가 생성돠고 제거됨.

5.3 참조 타입 변수의 ==, != 연산

  • ==, != 연산자: 변수의 값이 같은지, 아닌지를 조사함.
    • 참조 타입 변수에 대해서 번지를 비교함. 번지가 같다면 동일한 객체를 참조하는 것이고, 다르다면 다른 객체를 참조하는 것임.
// 두 배열 변수를 ==, != 연산으로 같은 배열을 참조하는지 검사하는 예제
public class ReferenceVariableCompareExample {
	public static void main(String[] args) {
		int[] arr1;
		int[] arr2;
		int[] arr3;

		arr1 = new int[] { 1, 2, 3 };
		arr2 = new int[] { 1, 2, 3 };
		arr3 = arr2;

		System.out.printIn(arr1 == arr2);	// false
		System.out.printIn(arr2 == arr3);	// true
	}
}

5.4 null과 NullPointerException

  • 참조 타입 변수: 아직 번지를 저장하고 있지 않다는 뜻으로 null 값을 가질 수 있음. null로 초기화된 참조 변수는 스택 영역에 생성됨.
  • 예외(Exception): 프로그램 실행 도중에 발생하는 오류
    • NullPointerException: 참조 변수를 사용하면서 가장 많이 발생하는 예외 중 하나. 변수가 null인 상태에서 객체의 데이터나 메소드를 사용하려 할 때 발생함. 해결하려면 참조 변수가 객체를 정확히 참조하도록 번지를 대입해야 함.
// NullPointerException가 발생하는 것을 확인하는 예제
public class NullPointerExceptionExample {
	public static void main(String[] args) {
		int[] intArray = null;
		intArray[0] = 10;		// NullPointerException

		String str = null;
		System.out.printIn("총 문자 수: " + str.length());	// NullPointerException
	}
}
  • 참조 타입 변수에 일부러 null을 대입하는 경우
    • 어떤 변수에서도 객체를 참조하지 않으면 해당 객체는 프로그램에서 사용할 수 없음.
    • 힙 메모리에는 있지만 위치 정보를 모르기 때문에 사용할 수 없음.
    • 자바는 이러한 객체를 쓰레기로 취급하고, 쓰레기 수집가(Garbage Collector)를 실행시켜 자동으로 제거함.
// 변수에 저장된 String 객체가 쓰레기가 되는지 확인하는 예제
public class GarbageObjectExample {
	public static void main(String[] args) {
		String hobby = "여행";
		hobby = null;	// "여행" 객체를 쓰레기로 만듦.
        
		String kind1 = "자동차";
		String kind2 = kind1;
		kind1 = null;	// "자동차" 객체는 쓰레기가 아님.
		System.out.printIn("kind2: " + kind2);	// kind2: 자동차
	}
}

5.5 문자열(String) 타입

  • 자바의 문자열은 String 객체로 생성됨.
  • 문자열 객체 생성 방법 
    • String 변수에 문자열 리터럴을 대입하는 것
    • new 연산자(객체 생성 연산자)로 직접 String 객체를 생성하고 대입하는 것
  • 문자열 비교
    • 문자열 리터럴로 생성하는지 new 연산자로 생성하는지에 따라 비교 연산자(==)의 결과가 달라질 수 있음.
    • 동일한 String 객체든 다른 String 객체든 상관없이 내부 문자열만을 비교할 경우에는 String 객체의 equals() 메소드를 사용함.
// 문자열 비교
String name1 = "홍길동";
String name2 = "홍길동";

String name3 = new String("홍길동");
String name4 = new String("홍길동");

name1 == name2 // true
name1.equals(name2) // true
name1 == name3	// false

name3 == name4 // false
name3.equals(name4) // true
  • 문자 추출
    • 문자열에서 특정 위치(인덱스)의 문자를 얻고 싶다면 charAt() 메소드를 사용함.
    • 인덱스: 0에서부터 '문자열의 길이-1'까지의 번호
// 문자 추출 예제
String subject = "자바 프로그래밍";
Char charValue = subject.charAt(3);	// 프
  • 문자열 길이
    • 문자열에서 문자의 개수를 얻고 싶다면 lengh() 메소드를 사용함.
// 문자열 길이 예제
String subject = "자바 프로그래밍";
int length = subject.length();	// 8
  • 문자열 대체
    • 문자열에서 특정 문자열을 다른 문자열로 대체하고 싶다면 replace() 메소드를 사용함.
    • replace() 메소드가 리턴하는 문자열은 원래 문자열의 수정본이 아니라 완전히 새로운 문자열임.
// 문자열 대체 예제
String oldStr = "자바 프로그래밍";
String newStr = oldStr.replace("자바", "JAVA");	// JAVA 프로그래밍
  • 문자열 잘라내기
    • 문자열에서 특정 위치의 문자열을 잘라내어 가져오고 싶으면 substring() 메소드를 사용한다.
// 문자열 잘라내기 예제
String ssn = "880818-1234567";
String firstNum = ssn.substring(0, 6);	// 880815
String secondNum = ssn.substring(7);	// 1234567
  • 문자열 찾기
    • 문자열에서 특정 문자열의 위치(인덱스)를 찾고자 할 때에는 indexOf() 메소드를 사용함.
    • indexOf() 메소드는 주어진 문자열이 포함되어 있지 않으면 -1을 리턴함.
    • 문자열이 단순히 포함되어 있는지만 조사하고 싶으면 contains() 메소드를 사용함.
// 문자열 찾기 예제
String subject = "자바 프로그래밍";
int index = subject.indexOf("프로그래밍");	// 3

boolean result = subject.contains("프로그래밍");	// true
  • 문자열 분리
    • 문자열에서 구분자를 사용하여 여러 개의 문자열로 따로 분리해서 얻고 싶으면 split() 메소드를 사용함.
// 문자열 분리 예제
String board = "번호, 제목, 내용, 성명";
String[] arr = board.split(",");	// arr[0] = "번호", arr[1] = "제목", arr[2] = "내용", arr[3] = "성명"

5.6 배열(Array) 타입

  • 변수: 하나의 값만 저장할 수 있음. 저장해야 할 값의 수가 많아지면 그만큼 많은 변수가 필요함.
  • 배열: 연속된 공간에 값을 나열시키고, 각 값에 인덱스(index)를 부여해 놓은 자료구조
  • 배열의 특징
    • 배열은 같은 타입의 값만 관리함.
    • 배열의 길이는 늘리거나 줄일 수 없음.
  • 배열 변수 선언
    •  배열 변수는 참조 변수임. 배열도 객체이므로 힙 영역에 생성되고 배열 변수는 힙 영역의 배열 주소를 저장함.
    • 배열 변수가 null 값을 가진 상태에서 변수[인덱스]로 값을 읽거나 저장하면 NullPointerException이 발생함.
// 배열 변수 선언 방법
/* 1) 타입[] 변수; -> 주로 사용하는 방법 */
int[] intArray;

/* 2) 타입 변수[]; */
int intArray[];
  • 값 목록으로 배열 생성
    • 배열에 저장될 값의 목록이 있으면 배열을 생성할 수 있음.
    • 배열 변수를 미리 선언한 후에는 값 목록을 변수에 대입할 수 없음. 배열 변수를 선언한 시점과 값 목록이 대입되는 시점이 다르면 new 타입[]을 중괄호 앞에 붙여줌.
    • 메소드의 매개변수가 배열 타입일 경우에도 컴파일 에러가 발생함.
// 값 목록으로 배열 생성
/* 타입[] 변수 = { 값0, 값1, 값2, 값3, ... }; */
String[] season = { "Spring", "Summer", "Fall", "Winter" };

// 배열의 값 변경
season[1] = "여름";

/* 타입[] 변수 = new 타입[] { 값0, 값1, 값2, 값3, ... }; */
String[] names = null;
names = new String[] { "신용권", "홍길동", "김자바" };
  • new 연산자로 배열 생성 
    • 값의 목록은 없지만 향후 값들을 저장할 목적으로 배열을 미리 생성할 수 있음.
    • new 연산자가 해당 길이의 배열을 생성하고 배열의 번지를 리턴하기 때문에, 배열 변수가 선언된 후에도 대입이 가능함.
// new 연산자로 배열 생성
/* 타입[] 변수 = new 타입[길이]; // 길이: 배열이 저장할 수 있는 항목 수 */
int[] intArray = new int[5];

/* 변수[인덱스] = 값; */
intArray[3] = 2;
데이터 타입 초기값
기본 타입 byte[]
char[]
short[]
int[]
long[]
0
'\u0000'
0
0
0L
float[]
double[]
0.0F
0.0
boolean[] false
참조 타입 클래스[]
인터페이스[]
null
null

▲ 타입별 배열의 초기값

  • 배열 길이
    • 배열 길이: 배열에 저장할 수 있는 항목 수
    • 배열의 length 필드는 읽기만 가능하고, 값을 변경할 수는 없음.
// 배열 길이
/* 배열변수.length; */
int[] intArray = { 1, 2, 3 }
intArray.length; // 3

 

이 글은 『이것이 자바다』 책을 학습한 내용을 정리한 것입니다.

'프로그래밍 > Java' 카테고리의 다른 글

[스터디4] 06. 제네릭  (0) 2025.03.02
[스터디4] 05. 중첩 선언과 익명 객체  (0) 2025.02.25
[스터디4] 04. 인터페이스  (1) 2025.02.16
[스터디4] 03. 상속  (0) 2025.02.09
[스터디4] 02. 클래스  (0) 2025.01.31
Comments