본문 바로가기

JAVA/이것이 자바다

Chapter .05 참조 타입

 

5.1 데이터 타입 분류

프로그램이 하는 일은 결국 데이터를 처리하는 것이다.

따라서 데이터를 얼마나 잘 다루느냐가 좋은 프로그램을 작성할 수 있는 관건이 된다.

데이터를 잘 다루기 위해서는 자바에서 지원하는 데이터 타입에 대해서 제대로 이해할 필요가 있다.

자바의 데이터 타입에는 크게 기본타입(원시 타입 : primitive type)과 참조타입(reference type)이 있다.

기본타입이란 정수, 실수, 문자, 논리 리터럴을 저장하는 타입을 말한다.

지금까지 우리는 기본 타입으로 변수를 선언하고 데이터를 저장하는 연습을 했다.

이번 장부터는 참조 타입에 중점을 두려고 한다.

참조 타입이란 객체(Object)의 번지를 참조하는 타입으로 배열, 열거, 클래스, 인터페이스 타입을 말한다.

//기본타입 변수
int age = 25;
double price = 100.5;

//참조타입 변수
String name = "신용권";
String hobby = "독서";

 

● 변수의 메모리 사용

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

  - 참조 타입 변수 주소를 통해 객체 참조

int와 double 변수인 age와 price는 직접 값을 저장하고 있지만, String 클래스 변수인 name과 hobby는 힙 영역의 String 객체 주소 값을 가지고 있다.

주소를 통해 객체를 참조한다는 뜻에서 String 변수를 참조타입 변수라고 한다.

 

5.2 메모리 사용 영역

본격적으로 참조 타입을 알아보기 전에 우선 JVM이 사용하는 메모리 영역에 대해서 알아보기로 하자.

java.exe로 jvm이 시작되면 jvm은 운영체제에서 할당받은 메모리영역(Runtime Data Area)을 다음과 같이 세부 영역으로 구분해서 사용한다.

Runtime Data Area

 

5.2.1 메소드(method) 영역

• JVM 시작할 때 생성

• 로딩된 클래스 바이트 코드 내용을 분석 후 저장

• 모든 스레드가 공유

 

메소드 영역에는 코드에서 사용되는 클래스(~.class)들을 클래스 로더로 읽어 클래스별로 런타임 상수풀(runtime constant pool), 필드(field) 데이터, 메소드(method) 데이터, 메소드 코드, 생성자(constructor) 코드 등을 분류해서 저장한다. 메소드 영역은 jvm이 시작 할 떄 생성되고 모든 스레드가 공유하는 영역이다.

 

 

힙(Heap) 영역

• JVM 시작할 때 생성

• 객체/배열 저장

• 사용되지 않는 객체는 Garbage Collector 가 자동 제거

 

힙 영역은 객체와 배열이 생성되는 영역이다.

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

참조하는 변수나 필드가 없다면 의미 없는 객체가 되기 때문에 이것을 쓰레기로 취급하고 jvm은 쓰레기 수집기(gabage collection)를 실행시켜 쓰레기 객체를 힙 영역에서 자동으로 제거한다.

그렇기 때문에 개발자는 객체를 제거하기 위해 별도의 코드를 작성할 필요가 없다.

 

 

JVM 스택(stack) 영역

 • 스레드 별 생성

 • 메소드 호출할 때마다 Frame을 스택에 추가(push)

 • 메소드 종료하면 Frame 제거(pop)

 

JVM스택 영역은 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당된다.자바 프로그램에서 추가적으로 스레드를 생성하지 않았다면 main 스레드만 존재하므로 JVM 스택도 하나이다.JVM 스택은 메소드를 호출할 때마다 프레임(Frame)을 추가 (push)하고 메소드가 종료되면 해당 프레임을 제거(pop)하는 동작을 수행한다.예외 발생시 printStackTrace() 메소드로 보여주는 Stack Trace의 각 라인은 하나의 프레임을 표현한다. PrintStackTrace() 메소드는 예외처리에서 설명한다.

 

 

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

기본 타입 변수의 ==, != 연산은 변수의 값이 같은지, 아닌지를 조사하지만 참조 타입 변수들 간의 ==, != 연산은 동일한 객체를 참조하는지, 다른 객체를 참조하는지 알아볼 떄 사용한다.참조 타입 변수의 값은 힙 영역의 객체 주소이므로 결국 주소의 값을 비교하는 것이 된다.동일한 주소의 값을 가지고 있다는 것은 동일한 객체를 참조한다는 의미이다.따라서 동일한 객체를 참조하고 있을 경우 == 연산의 결과는 true이고, != 연산의 결과는 false이다.

 

refVar1 == refVar2          //false
refVar1 != refVar2          //true

refVar2 == refVar3          //true
refVar2 != refVar3          //false

 

5.4 null과 NullPointerException

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

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

참조 타입 변수가 null값을 가지는지 확인하려면 다음과 같이 ==, !=연산을 수행하면 된다.

상기 그림에서 refVal1은 힙 영역의 객체를 참조하므로 연산의 결과는 다음과 같다.

 

refVar1 == null           // false
refvar1 != null           // true

refVar2 == null           // true
refVar2 != null           // false

 

자바에서 프로그램 실행 도중 발생하는 오류를 예외(Exception) 이라고 말한다. 예외는 사용자의 잘못도니 입력으로 ㅂ라생할 수도 있고, 프로그래머가 코드를 잘못 작성해서 발생할 수도 있다.

참조변수를 사용하면서 가장 많이 발생하는 예외 중 하나로 NullPointerException이 있다.

이 예외는 참조변수를 잘못 사용하면 발생한다.

 

참조 타입 변수가 null을 가지고 있을 경우, 참조 타입 변수는 사용할 수 없다.

참조 타입 변수를 사용한느 것은 곳 객체를 사용하는 것을 의미하는데, 참조할 객체가 없으므로 사용할 수가 없는 것이다.

그러나 프로그래머의 실수로 null 값을 가지고 있는 참조 타입 변수를 사용하면 NullPointerException이 발생한다.

int[] intArray = null;
intArray[0] = 10;                //NullPointerException

 

 

상기 코드에서 intArray는 배열 타입 변수이므로 참조 타입 변수이다.

그래서 null로 초기화가 가능하다.

이 상태에서 intArray[0]에 10을 저장하려고 하면 NullPointerException이 발생한다.

이유는 intArray변수가 참조하는 배열 객체가 없기 때문이다.

String str = null;
System.out.println("총 문자수 : "+str.lenght());     //NullPointerException

String은 클래스 터ㅏ입이므로 참조 타입이다.

따라서 str변수도 null로 초기화가 가능하다.

이 상태에서 String 객체의 length()라는 메소드를 호출 하면 NullPointerException이 발생한다.

str변수가 참조하는 String 객체가 없기 때문이다.

프로그램 실행 도중 NullPointerException이 발생하면, 예외가 발생된 곳에서 객체를 참조하지 않은 상태로 참조 타입 변수를 사용하고 있음을 알아야 한다.

대처 방법은 이 변수를 추적해서 객체를 참조하도록 수장해야 한다.

NullPointerException은 아마 여루분이 앞으로 가장 많이 볼 수 있는 예외 중 하나일 것이다.

 

5.5 String 타입

자바는 문자열을 String 변수에 저장한다.

선언과 동시에 클 따옴표로 감싼 문자열 리터럴을 대입 할 수 있다.

String name = "신용권";

 

사실 문자열을 String 변수에 저장한다는 말은 틀린 표현이 아니다.

문자열이 직접 변수에 저장되는 것이 아니라, 문자열은 String 객체로 생성되고 변수는 String 객체를 참조한다.

 

String name = "신용권";
String hobby = "자바";

위 그림을 보면 name 변수와 hobby 변수는 스택 영역에 생성되고, 문자열 리터럴인 "신용권"과 "자바"는 힙 영역에 String 객체로 생성된다.

그리고 name 변수와 hobby 변수에는 String 객체의 주소 값이 저장된다.

자바는 문자열 리터럴이 동일하다면 String 객체를 공유하도록 되어 있다.

 

다음과 같이 name1과 name2가 동일한 문장려 리터럴인 "신용권을"참조할 경우 name1과 name2는 동일한 String 객체를 참조한다.

String name1 = "신용권";
String name2 = "신용권";

 

일반적으로 변수에 문자열을 저장할 경우에는 문자열 리터럴을 사용하지만, new 연산자를 사용해서 직접 String 객체를 생성시킬 수도 있다.

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

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

이 경우 name1과 name2는 서로 다른 String 객체를 참조한다.

 

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

동일한 문자열 리터럴로 String 객체를 생성했을 경우 == 연산의 결과는 true가 나오지만,

new 연산자로 String 객체를 생성했을 경우 == 연산의 결과는 false가 나온다.

== 연산자는 변수에 저장된 객체 번지가 동일한지를 검사하기 때문이다.

String name1 = "신민철";
String name2 = "신민철";
String name3 = new String("신민철");

name1과 name2는 동일한 문자열 리터럴로 생성된 객체를 참조하기 때문에 name1==name2의 결과는 true가 나온다.

그러나 name3은 new 연산자로 String 객체를 별도로 생성했기 때문에 name1==name2은 false가 나온다.

동일한 String 객체이건 다른 String 객체이건 사오간없이 문자열만을 비교할때는 String 객체의 equals() 메소드를 사요해야 한다.

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

String name1 = "신민철";
String name2 = "신민철";
String name3 = new String("신민철");

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

 

String 변수는 참조 타입이므로 초기값으로 null을 대입 할 수 있다.

null은 String 변수가 참조하는 String 객체가 없다는 뜻이다.

 

다음 코드처럼 hobby 변수가 String 객체를 참조 하였으나, null을 대입 함으로써 더이상 String 객체를 참조하지 않도록 할 수도 있다.

String hobby = "여행";
hobby = null;

그렇다면 참조를 잃은 String 객체는 어떻게 될까?

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

 

 

5.6 배열타입

5.6.1 배열이란?

같은 타입의 데이터를 연속된 공간에 저장하는 자료구조

각 데이터 저장 위치는 인덱스 부여해 접근

 

변수는 한 개의 데이터만 저장할수 있다. 따라서 저장해야 할 데이터의 수가 많아지면 그만큼 많은 변수가 필요하다.

예를들어 학생 30명의 성적을 저장하고, 평균값을 구한다고 가정해보자.

먼저 학생 30명의 성적을 저장하기 위해 변수 30개를 선언 해야 한다.

int score1 = 83;
int score2 = 83;
int score3 = 90;
int score4 = 91;
      *
      *
      *
int score30 = 83;

그리고 평점을 구하기 위해 변수들을 모두 더해야 한다.

int sum = score1;
sum += score2;
sum += score3;
     *
     *
     *
sum += score30;
int avg = sum/30;

위와 같은 방법은 매우 비효울적이고 지루한 코딩이 된다.

같은 타입의 많은 양의 데이터를 다루는 프로그램에서는 좀 더 효율적인 방법이 필요한데 이것이 바로 배열이다.

 

배열은 같은 타입의 데이터를 연속된 공간에 나열시키고, 각 데이터에 인덱스(index)를 부여해 놓은 자료구조이다.

예를 들어 학생들의 성적은 다음과 같이 score 배열로 생성할 수 있다.

배열의 구조

score[인덱스]

 

 

5.6.2 배열 선언

배열을 사용하기 위해서는 우선 배열 변수를 선언해야 한다.

배열 변수 선언은 다음과 같이 두가지 형태로 작성할 수 있다.

타입[ ] 변수;
타입 변수[ ];

대괄호[ ]는 배열 변수를 선언하는 기호로 사용되는데, 타입 뒤에 붙을 수도 있고 변수 뒤에 붙을 수도 있다.

타입은 배열에 저장될 데이터의 타입을 말한다.

다음은 각 타입별로 배영을 선언하는 예를 보여준다.

int[] intArray;                   int intArray[];
double[] doubleArray;             double doubleArray[];
String[] strArray;                String strArray[];

배열 변수는 참조 변수에 속하낟.

배열도 객체이므로 힙 영역에 생성되고 배열 변수는 힙 영역의 배열 객체를 참조하게 된다.

참조할 배열 객체가 없다면 배열 변수는 null값으로 초기화 될 수 있다.

타입[ ] 변수 = null;

만약 배열 변수가 null 값을 가진 상태에서 변수[인덱스]로 값을 읽거나 저장하게 되면 NullPointerException이 발생한다.

배열 변수는 배열을 생성하고 참조하는 상태에서 값을 저장하거나 읽어야 한다.

 

5.6.3 값 목록으로 배열 생성

배열 항목에 저장될 값의 목록이 있다면, 다음과 같이 간단하게 배열 객체를 만들 수 있다.

데이터타입[ ] 변수 = { 값0, 값1, 값2, 값3, ....};

중괄호 { } 는 주어진 값들의 항목으로 가지는 배열의 객체를 힙에 생성하고, 배열 객체의 번지를 리턴한다.

배열 변수는 리터럴된 번지를 저장함으로써 참조가 이루어진다.

 

예를들어 "신용권", "홍길동", "김자바" 문자열을 갖는 배열은 다음과 같이 생성할 수 있다.

String[] names = {"신용권", "홍길동", "김자바"};

이렇게 생성된 배열에서 "신용권은" names[0], "홍길동"은 names[1], "김자바"는 names[2]로 읽을 수 있다.

names[1]의 "홍길동"을 "홍삼원"으로 바꾸고 싶다면 다음과 같이 대입 연산자를 사용하면 된다.

names[1] = "홍삼원";

 

 

5.6.4 new 연산자로 배열 생성

값의 목록을 가지고 있지 않지만, 향후 값들을 저장할 배열을 미리 만들고 싶다면 new 연산자로 다음과 같이 배열 객체를 생성시킬 수 있다.

길이는 배열이 저장 할 수 있는 값의 수를 말한다.

new 연산자로 배열을 생성할 경우에는 이미 배열 변수가 선언된 후에도 가능하다.

다음은 길이 5인 int[ ]배열을 생성한다.

int[] intArray = neww int[5];

자바는 intArray[0] ~ intArray[4]까지 값이 저장될 수 있는 공간을 확보하고, 배열의 생성 번지를 리턴한다.

리턴된 번지는 intArray 변수에 저장된다. 각각의 항목 크기는 다음과 같이 int 타입의 크기인 4byte이다.

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

 

학생 30명의 점수를 젖아 할 배열을 다음과 같이 생성한다고 가정해보자.

int[] scores = new int[30];

scores배열은 int 타입 배열이므로 다음과 같이 scores[0] ~ scores[29]까지 모두 기본값 0으로 초기화 된다.

만약 String 배열 names를 생성했다면 names[0]에서 names[29]까지 모두 null로 초기화 된다.

타입별 초기값

 

배열이 생성되고 나서 값을 저장하려면 대입 연산자를 사용하면 된다.

변수[인덱스] = 값;

int[] scores = new int[3];
score[0] = 1;
score[1] = 2;
score[2] = 3;

score[0] = 4;                     //대입 연산자를 이용하여 scores[0]을 변경

 

 

5.6.5 배열 길이

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

코드에서 배열의 길이를 얻으려면 다음과 같이 배열 객체의 length 필드를 읽으면 된다.

참고로 필드는 객체 내부의 데이터를 말하낟.

배열의 length 필드를 읽기 위해서는 배열 변수에 도트(.) 연산자를 붙이고 length를 적어주면 된다.

배열변수.length;

 

다음은 배열 intArray의 길이를 알아보는 코드이다.

배열 intArray가 3개의 값을 가지고 있기 때문에 num 변수에는 3이 저장된다.

int[] intArray = {10, 20, 30};
int num = intArray.length;

length는 읽기 전용 필드이기 때문에 값을 바꿀수가 없다.

그래서 다음과 같이 작성하면 안된다.

intArray.length = 10;            //잘못된 코드

 

만약 배열 인덱스를 초과해서 사용하면 ArrayIndexOutOfBoundsException이 발생한다.

int[] intArray = {10, 20, 30};
intArray[3] = 10;                 //intArray의 index는 2까지 이기 때문에
                                  //2를 초과한 3을 호출하면 에러가 발생한다.

 

5.6.6 커맨드 라인 입력

우리는 이제 프로그램 실행을 위해 main()메소드가 필요하다는 것을 알고 있다.

하지만 main()메소드의 매개값인 String[ ] args 가 왜 필요한 것인지 궁금하엿을 것이다.

이제 이 궁금증을 풀어보자.

public static void main(String[] args){ .... }

"java 클래스"로 프로그램을 실행하면 JVM은 길이가 0인 String 배열을 먼저 생성하고 main() 메소드를 호출할 때 매개값으로 전달한다.

만약 다음과 같이 "java 클래스" 뒤에 공백으로 구분된 문자열 목록을 주고 실행하면, 문자열 목록으로 구성된 String[ ] 배열이 생성되고 main( ) 메소드를 호출할 떄 매개값으로 전달된다.

 

 

5.6.7 다차원 배열

지금까지 살펴본 배열은 값 목록으로 구성된 1차원 배열이였다.

이와는 달리 값들이 행과 열로서 구성된 배열을 2차원 배열이라고 한다.

2차원 배열은 수학의 행렬을 떠올리면 되는데, 가로 인덱스와 세로 인덱스를 사용한다. 

자바는 주로 2차원 배열을 중첩 배열 방식으로 구현한다.

int[][] scores = new int[2][3];

 

이 코드는 메모리에 다음과 같이 세 개의 배열 객체를 생성한다.

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

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

scores[0]과 scores[1]은 모두 배열 변수를 참조하는 변수 역할을 한다.

따라서 각 배열의 길이는 다음과 같이 얻을 수 있다.

scores.lenght                 //2(배열 A의 길이)
scores[0].lenght              //2(배열 B의 길이)
scores[1].lenght              //3(배열 C의 길이)

생성 원리는 수학 행렬과는 근본적으로 다르지만 사용 방식은 행렬과 동일하다.

scores[0][1]은 배열 B의 인덱스 1 값을 뜻한다.

수학 행렬에서는 (0, 1) 값이라고 볼 수 있다.

마찬가지로 scores[1][0]은 배열 C의 인덱스 0값을 뜻한다.

이것은 수학 행렬의 (1, 0) 값이다.

자바는 일차원 배열이 서로 연결된 구조로 다차원 배열을 구현하기 때문에 수학 행렬구조가 아닌 계단식 구조를 가질 수 있다.

 

5.6.8 객체를 참조하는 배열

기본 타입(byte, char, short, int, long, float, double, boolean) 배열은 각 항목에 직접 값을 갖고 있지만, 참조타입(클래스, 인터페이스) 배열은 각 항목에 객체의 번지를 가지고 있다.

 

예를 들어 String은 클래스 타입이므로 String[ ] 배열은 각 항목에 문장려이 아니라, String 객체의 주소를 가지고 있다.

즉 String 객체를 참조하게 된다.

String[] strArray = new String[3];
strArray[0] = "Java";
strArray[1] = "C++";
strArray[2] = "C#";

위 코드는 배열 변수 strArray를 선언하고 3개의 문자열을 참조하는 배열을 생성한다. 

따라서 배열 항목도 결국 String 변수와 동일하게 취급되어야 한다.

예를 들어 String[] 배열 항목간에 문자열을 비교하기 위해서는 == 연산자 대신 equals() 메소드를 사용해야 한다.

==는 객체의 번지 비교이기 때문에 문자열 비교에 사용할 수 없다.

 

5.6.9 배열 복사

배열은 한 번 생성하면 크기를 변경할 수 없기 때문에 더 많은 저장 공간이 필요하다면 보다 큰 배열을 새로 만들고 이전 배열로부터 항목 값들을 복사해야 한다.

 

배열 간의 항목 값들을  복사하려면 for문을 사용하거나 System.arraycopy() 메소드를 사용하면 된다.

for문으로 배열을 복사하는 코드는 다음과 같다.

int[] oldIntArray = { 1, 2, 3 };
int[] newIntArray = new int[5];

for(int i=0; i<oldIntArray.length;i++){
     newIntArray[i] = oldIntArray[i];
}

 

이번에는 System.arraycopy를 이용해서 배열을 복사해보자.

System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

// src     : 원본 배열
// srcPos  : 복사할 항목의 시작 index
// dest    : 새 배열
// destPos : 새 배열에서 붙여넣을 시작 인덱스
// length  : 복사 할 개수

예를들어 원본 배열이 arg1이고 새 배열이 arg2일 경우 ar1의 모든 항목을 arr2에 복사하려면 다음과 같이 System.arraycopy() 메소드를 호출하면 된다.

System.arraycopy(arg1, 0, arg1, 0, arg1.length);

복사되지 않은 항목은 배열의 기본 초기값으로 유지된다.

 

 

5.6.10 향상된 for문

배열 및 컬렉션(15장에서 다룸)의 항목 요소를 순차적으로 처리

인덱스 이용하지 않고 바로 항목 요소 반복

 

자바 5부터 배열 및 컬렉션 객체(15장에서 학습)를 좀 더 쉽게 처리할 목적으로 향상된 for문을 제공한다.

향상된 for문은 반복 실행을 하기 위해 카운터 변수와 증감식을 사용하지 않는다.

배열 및 컬렉션 항목의 개수만큼 반복하고, 자동적으로 for문을 빠져나간다.

for문의 괄호( )에는 배열에서 꺼낸 항목을 저장할 변수 선언과 콜론( : ) 그리고 배열을 나란히 작성한다.

for문이 처음 실행될 때 ①배열에서 가져올 첫 번째 값이 존재하는지 평가한다.

가져올 값이 존재하면 해당 값을 ②변수에 저장한다.

그리고 ③실행문을 실행한다.

블록 내부의 ③실행문이 모두 실행되면 다시 루프를 돌아 ①배열에서 가져올 값이 존재하는지 평가한다.

만약 다음 항목이 존재하면 ② → ③ → ① 로 다시 진행하고, 가져올 다음 항목이 없으면 for문이 종료된다.

따라서 for문의 반복 횟수는 배열의 항목 수가 된다.

int[] scores = {95, 71, 84, 93, 84};

int sum = 0;
for(int score : scores){
	sum = sum + score;
}

 

 

5.7 열거타입

 한정된 값만을 갖는 데이터 타입

 한정된 값은 열거 상수(Enumeration Constant)로 정의

 

데이터 중에서는 몇 가지로 한정된 값만을 갖는 경우가 흔히 있다.

예를 들어 요일에 대한 데이터는 월, 화, 수, 목, 금, 토, 일 이라는 일곱 개의 값만을 갖고, 계절에 대한 데이터는 봄, 여름, 가을, 겨울 이라는 네개의 값만을 갖는다.

 

이와 같이 한정된 값만을 갖는 데이터 타입이 열거 타입이다.

열거 타입(Enumeration type)은 몇 개의 열거 상수중에서 하나의 상수(Enumeration Constant)를 저장하는 데이터 타입이다.

 

5.7.1 열거 타입 선언

파일 이름과 동일한 이름으로 다음과 같이 선언 (첫 글자 대문자)

한정된 값인 열거 상수 정의

  - 열거 상수 이름은 관례적으로 모두 대문자로 작성

  - 다른 단어가 결합된 이름일 경우 관례적으로 밑줄( _ )로 연결

 

열거 타입을 선언하기 위해서는 먼저 열거 타입의 이름을 정하고 열거 타입 이름으로 소스파일(.java)를 생성해야 한다.

열거타입 이름은 관례적으로 첫 문자를 대문자로 하고 나머지는 소문자로 구성한다.

만약 여러 단어로 구성된 이름이라면 단어 첫 문자는 대문자로 하는 것이 관례이다.

Week.java
MemberGrade.java
ProductKind.java

소스 파일의 내용으로는 다음과 같이 열거 타입 선언이 온다.

public enum 키워드는 열거 타입을 선언하기 위한 키워드 이다.

반드시 소문자로 작성해야 한다.

열거 타입 이름은 소스 파일명과 대소문자가 모두 일치해야 한다.

public enum 열거타입 이름 {..... }

 

열거 타입을 선언했다면 이제는 열거 상수를 선언하면 된다.

열거 상수는 열거 타입의 값으로 사용되는데, 관례적으로 열거 상수는 모두 대문자로 작성한다.

public enum Week { MONDAY, TUESDAY, WENDESDAY, THURSDAY, FRIDAY, ---- }

열거타입 선언과 열거 상수 작성

만약 열거 상수가 여러 단어로 구성될 경우에는 단어 사이를 밑줄( _ )로 연결하는 것이 관례이다.

예를 들면 다음과 같다.

public enum LoginResult {LOGIN_SUCCESS, LOGIN_FILAED}

 

5.7.2 열거 타입 변수

열거 타입을 선언했다면 이제 열거 타입을 사용할 수 있다.

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

열거타입 변수;

예를들어 열거타입 Week로 변수를 선언하면 다음과 같다.

Week today;
Week reservationDay;

열거타입을 선언했다면 열거 상수를 저장할 수 있다.

열거 상수는 단독으로 사용할 수는 없고 반드시 열거타입.열거상수로 사용된다.

Week today = Week.SUNDAY;

열거타입 변수는 null값을 저장 할 수 있는데 열거 타입도 참조 타입이기 때문이다.

Week birthday = null

열거 상수는 열거 객체로 생성된다.

열거 타입 Week의 경우 MONDAY부터 SUNDAY까지의 열거 상수는 7개의 객체로 생성된다.

 

Week today = Week.SUNDAY;

열거 타입 변수 today는 스택 영역에 생성된다.

today에 저장되는 값은 Week.SUNDAY 열거 상수가 참조하는 객체의 번지이다.

따라서 열거 상수 Week.SUNDAY와 today 변수는 서로 같은 Week 객체를 참조하게 된다.

 

5.7.3 열거 객체의 메소드

 열거 객체는 열거 상수의 문자열을 내부 데이터로 가지고 있음

 열거 타입은 컴파일 시 java.lang.Enum 클래스를 자동 상속

  - 열거 객체는 java.lang.Enum  클래스의 메소드 사용 가능

 

열거 객체는 열거 상수의 문자열을 내부 데이터로 가지고 있다.

java.lang.Enum 클래스에 선언된 메소드를 열거 객체에서 사용할 수 있는데 모든 열거 타입은 컴파일시에 Enum 클래스를 상속하게 되어 있기 때문이다.

'JAVA > 이것이 자바다' 카테고리의 다른 글

Chapter .06-2 클래스  (0) 2021.07.16
Chapter .06-1 클래스  (0) 2021.07.14
Chapter .04 조건문과 반복문  (0) 2021.07.05
Chapter .03 연산자  (0) 2021.07.02
Chapter .02 변수와 타입  (0) 2021.07.01