반응형

출처 : 이것이 자바다

참조 타입

5.1 데이터 타입 분류

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

=> 데이터 타입 : 저장되는 값이 무엇이냐이다.

1) 기본 타입은 정수 ,실수, 문자 , 논리 리터럴을 저장하는 타입

byte, char, short, int, long, float, double, boolean을 이용해서 선언된 변수는 실제 값을 변수 안에 저장하지만,

2) 참조 타입인  객체(Object) 의 번지를 참조하는 타입으로

배열, 열거, 클래스, 인터페이스를 이용해서 선언된 변수는 메모리 번지를 값으로 갖는다.

   번지를 통해 객체를 참조한다는 뜻에서 참조 타입이라고 부른다.

 

변수가 스택 영역에 생성되고, 객체는 힙 영역에 생성된다

 

 

 

 

메모리상에서 이 변수들이 갖는 값을 그림으로 표현하면 오른쪽 그림이다.

변수가 스택 영역에 생성되고 객체는 힙 영역에 생성되는 것이다.

int double 변수인 ageprice는 직접 값을 저장하고 있지만 ,String클래스 변수인 namehobby는 힙 영역의 String 객체 주소 값을 가지고 있다. 주소를 통해 객체를 참조한다는 뜻에서 String 클래스 변수를 참조 타입 변수라고 한다.

 

5.2 메모리 사용 영역

JVM이 사용하는 메모리 영역

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

 

5.2.1 메소드(Method) 영역

=>메소드 영역

메소드 영역에는 코드에서 사용되는 클래스(.~class)들을 클래스 로더로 읽어 클래스별로 런타임 상수풀(runtime constant pool),필드(field) 데이터, 메소드(Method) ,메소드 코드 , 생성자(constructor)코드 등을 분류해서 저장한다.

메소드 영역은 JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역이다.

JVM 시작할 때 생성

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

모든 스레드가 공유

 

=>힙 영역

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

JVM 시작할 때 생성

객체/배열 저장

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

힙 영역에도 두가지가 있다.

 

=>JVM 스택

스레드 별 생성

추가적으로 스레드를 생성하지 않았담녀 main 스레드만 존재하므로 JVM스택도 하나이다.

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

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

예외 발생시 printStackTrace()메소드로 보여주는 Stack Trace의 각 라인은 하나의 프레임을 표현한다. printStackTrace() 메소드는 예외 처리에서 설명한다.

프레임 내부에는 로컬 변수 스택이 있는데 , 기본 타입 변수와 참조 타입 변수가 추가 (push) 되거나 제거(pop)된다.변수가 이 영역에 생성되는 시점은 초기화가 될 때, 즉 최초로 변수에 값이 저장될 떄이다. 변수는 선언된 블록 안에서만 스택이 존재하고 블록을 벗어나면 스택에서 제거된다.

 

스택의 생성 및 소멸

 

기본 타입 변수는 스택 영역에 직접 값을 가지고 있지만  , 참조 타입 변수는 값이 아니라 힙 영역이나 메소드 영역의 객체 주소를 가진다.

 

배열 변수 scores에는 배열의 힙 영역의 주소가 저장된다.

 

 

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

변수의 값이 같은지 다른지 비교

=>기본 타입: byte, char, short, int, long, float, double, boolean

의미 : 변수의 값이 같은지 다른지 조사

=>참조 타입: 배열, 열거, 클래스, 인터페이스

의미 : 동일한 객체를 참조하는지 다른 객체를 참조하는지 조사

 

 

5.4 nullNullPointerException

=> null()

변수가 참조하는 객체가 없을 경우 초기값으로 사용 가능

참조 타입의 변수에만 저장가능

null로 초기화된 참조 변수는 스택 영역 생성

 

 

 

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

 

 

 

=> NullPointerException의 의미

예외(Exception) : 자바는 프로그램 실행 도중에 발생하는 오류를 예외라고 부른다.

사용자의 잘못된 조작 이나 잘못된 코딩으로 인해 발생하는 프로그램 오류

NullPointerException

참조 변수가 null 값을 가지고 있을 때

객체의 필드나 메소드를 사용하려고 했을 때 발생

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

 

 

 

 

 

 

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

 

 

 

 

 

 

String은 클래스 타입이므로 참조 타입이다.참조하는 String객체가 없기 때문이다.

 

5.5 String타입

문자열을 저장하는 클래스 타입

String 변수;

큰 따옴표로 감싼 문자열 리터럴을 대입하면 된다.

변수 = "문자열";

 

변수 선언과 동시에 문자열을 저장할 수도 있다.

String 변수 = "문자열";

 

다음은 두 개의 String 변수를 선언하고 문자열을 저장한다.

 

 

 

 

 

 

 

문자열은 String 객체로 생성되고 변수는 String 객체를 참조한다.

 

문자열 리터럴 동일하다면 String 객체 공유

 

 

 

 

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

=>new 연산자를 이용한 String 객체 생성

힙 영역에 새로운 String 객체 생성

String 객체를 생성한 후 번지 리턴

 

 

 

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

 

 

String name1 = "신민철";

String name2 = "신민철";

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

 

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

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

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

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

 

문자열은 String 객체로 생성되고 변수는 String 객체를 참조한다.

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

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

 

[StringEqualsExample.java]문자열 비교

public class StringEqualsExample {

       public static void main(String[] args) {

               String strVar1 = "신민철";

               String strVar2 = "신민철";

 

               if (strVar1 == strVar2) {

                      System.out.println("strVar1 strVar2 참조가 같음");

               } else {

                      System.out.println("strVar1 strVar2 참조가 다름");

               }

 

               if (strVar1.equals(strVar2)) {

                      System.out.println("strVar1 strVar2 참조가 문자열이 같음");

               }

 

               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 strVar4 문자열이 같음");

               }

 

       }

}

 

== 연산자는 변수에 저장된 객체 번지가 동일한지를 검사한다

equals() 메소드는 문자열만을 비교한다

 

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

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

ex)

String hobby = null;

 

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

참조를 잃는 String 객체는 JVM 쓰레기 객체로 취급하고 쓰레기 수집기를 구동시켜 메모리에서 자동 제거한다.

ex)

String hobby = "여행";

hobby = null;

 

 

5.6 배열 타입

5.6.1 배열이란 ?

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

 

성적

 

 

 

평균

 

 

 

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

 

=>배열이란?

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

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

 

 

 

 
 

 

 

 

 

 

score[인덱스]

 

==>배열의 장점

중복된 변수 선언 줄이기 위해 사용

반복문 이용해 요소들을 쉽게 처리

 

배열은 선언과 동시에 저장할 수 있는 데이터 타입이 결정된다.

만약 다른 타입의 값을 저장하려고 하면 타입 불일치(Type mismatch)컴파일 오류가 발생한다.

배열의 또 다른 특징은 한번 생성된 배열은 길이를 늘리거나 줄일 수 없다.

 

5.6.2 배열 선언

배열을 사용하기 위해 우선 배열 변수 선언

두가지 형태:

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

 

 

대괄호 []는 배열 변수를 선언하는 기호로 사용되는데 , 타입 뒤에 붙을 수도 있고 변수 뒤에 붙을 수도 있다.타입은 배열에 저장될 데이터의 타입을 말한다.

 

배열 변수는 참조 변수에 속한다.

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

배열 변수는 참조 변수 - 배열 생성되기 전 null로 초기화 가능

타입[] 변수 = null;

배열 변수가 null 값을 가진 상태에서 항목에 접근 불가

변수[인덱스]” 못함

NullPointerException 발생

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

 

5.6.3 값 목록으로 배열 생성

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

변수 선언과 동시에 값 목록 대입

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

 

 

 

 

 

 

중괄호 {}는 주어진 값들을 항목으로 가지는 배열 객체를 힙에 생성하고 , 배열 객체의 번지를 리턴한다. 배열 변수는 리턴된 번지를 저장함으로써 참조가 이루어진다.

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

값을 바꾸고 싶다면 다음과 같이 대입 연산자를 사용하면 된다.

names[1] = "홍삼원";

 

[ ArrayCreateByValueListExample1.java]값 목록으로 배열 생성

public class ArrayCreateByValueListExample1 {

 

       public static void main(String[] args) {

 

               int[] score = { 83, 90, 87 };

               System.out.println("score[0] : " + score[0]);

               System.out.println("score[1] : " + score[1]);

               System.out.println("score[2] : " + score[2]);

 

               int sum = 0;

               for (int i = 0; i < 3; i++) {

                      sum += score[i];

               }

 

               System.out.println("총합 : " + sum);

               double avg = (double) sum / 3;

               System.out.println("평균 : " + avg);

 

       }

}

 

변수 선언 후 값 목록 대입 -> 컴파일 에러

 

 

=>값 목록으로 배열 생성

배열 변수를 미리 선언한 후 , 값 목록들이 나중에 결정되는 상황이라면 new연산자를 사용하면 된다.

변수 = new 타입[]{ 0, 1, 2, 3, ... };

 

:

String[] names = null;

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

 

메소드의 매개값이 배열일 경우에도 마찬가지이다.

add()메소드가 있을 경우 ,값 목록으로 배열을 생성함과 동시에 add()메소드의 매개값으로 사용하고자 할 떄는 반드시 new연산자를 사용해야 한다.

int add(int[] scores){ ... }

int result = add( {95, 85, 90} ) ;//컴파일 에러

int result = add( new int[] {95, 85, 90});

 

[ ArrayCreateByValueListExample2.java]값의 리스트로 배열 생성

public class ArrayCreateByValueListExample2 {

       public static void main(String[] args) {

               int[] scores;

               scores = new int[] { 83, 90, 87 };

               int sum1 = 0;

               for (int i = 0; i < 3; i++) {

                      sum1 += scores[i];

               }

 

               System.out.println("총합 : "+sum1);

               //리턴된 총합을 sum2 저장

               int sum2 = add(new int[] { 83, 90, 87 });

               System.out.println("총합 : "+sum2);

               System.out.println();

 

       }

      

       //총합을 계산해서 리턴하는 메소드

       public static int add(int[] scores) {

               int sum = 0;

               for (int i = 0; i < 3; i++) {

                      sum += scores[i];

               }

 

               return sum;

       }

}

 

5.6.4 new 연산자로 배열 생성

배열 생성시 값 목록을 가지고 있지 않음

향후 값들을 저장할 배열을 미리 생성하고 싶을 경우

 

타입[] 변수 = new 타입[길이];//길이는 배열이 저장할 수 있는 값의 수를 말한다.

 

타입[] 변수 = null;
변수 = new 타입[길이];

 

 

 
 

 

 

 

 

 

 

 

 

저장될 수 있는 공간을 확보하고 , 배열의 생성 번지를 리턴한다. 리턴된 번지는 intArray변수에 저장한다. 4byte이다.

 

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

int [] scores = new int[30];

 

String배열

String[] names = new String[30];

 

==>타입별로 배열의 초기값:

 

 

 

 

 

 

 

 

 

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

변수[인덱스] = ;

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

int [] scores = new int[3];

scores[0] = 83;

scores[1] = 90;

scores[2] = 75;

 

[ ArrayCreateByNewExample.java]new 연산자로 배열 생성

public class ArrayCreateByNewExample {

 

    public static void main(String[] args) {

 

        int[] arr1 = new int[3];

        for (int i = 0; i < 3; i++) {

            System.out.println("arr1[" + i + "] : " + arr1[i]);

        }

 

        arr1[0] = 10;

        arr1[1] = 20;

        arr1[2] = 30;

 

        for (int i = 0; i < 3; i++) {

            System.out.println("arr1[" + i + "] : " + arr1[i]);

               }

       

        double[] arr2 = new double[3];

        for (int i = 0; i < 3; i++) {

            System.out.println("arr2[" + i + "] : " + arr2[i]);

        }

 

        arr2[0] = 0.1;

        arr2[1] = 0.2;

        arr2[2] = 0.3;

 

        for (int i = 0; i < 3; i++) {

            System.out.println("arr2[" + i + "] : " + arr2[i]);

               }

       

        String[] arr3 = new String[3];

        for (int i = 0; i < 3; i++) {

            System.out.println("arr3[" + i + "] : " + arr3[i]);

        }

 

        arr3[0] = "1";

        arr3[1] = "2";

        arr3[2] = "3";

 

        for (int i = 0; i < 3; i++) {

            System.out.println("arr3[" + i + "] : " + arr3[i]);

               }

       }

}

 

5.6.5 배열 길이

배열에 저장할 수 있는 전체 항목 수

코드에서 배열의 길이 얻는 방법

 

:

 

 

배열의 길이는 읽기 전용

 

배열의 길이는 for문의 조건식에서 주로 사용

 

 

 

[ ArrayLengthExample.java]배열의 length 필드

public class ArrayLengthExample {

           public static void main(String[] args) {

                       int[] scores = { 83, 90, 87 };

 

                       int sum = 0;

                       for (int i = 0; i < scores.length; i++) {

                                  sum += scores[i];

                       }

                       System.out.println("총합 : " + sum);

 

                       double avg = (double) sum / scores.length;

                       System.out.println("평균 : " + avg);

           }

}

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

배열의 인덱스 범위는 0 ~ (길이-1)이다.

 

5.6.6 커맨드 라인 입력

main()메소드

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

 

배열의 선언과 사용

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

 

문자열 목록으로 구성된 String[] 배열이 생성되고 main()메소드를 호출 할 때 매개값으로 전달된다.

 

[ MainStringArrayArgument.java]main() 메소드의 매개 변수

public class MainStringArrayArgument {

           public static void main(String[] args) {

                       if (args.length != 2) { // 입력된 데이터 개수가 2개가 아닐 경우

                                  System.out.println("프로그램의 사용법");

                                  System.out.println("java MainStringArrayArgument num1 num2");

                                  System.exit(0);

                       }

 

                       String strNum1 = args[0];

                       String strNum2 = args[1];

 

                       int num1 = Integer.parseInt(strNum1); // 문자열을 정수로 변환

                       int num2 = Integer.parseInt(strNum2);

 

                       int result = num1 + num2;

                       System.out.println(num1 + " + " + num2 + " = " + result);

           }

}

이클립스에서 프로젝트 오른쪽 마우스 클릭

Run ->Run Configurations

 

 

 

 

 

명령어 cmd에서

java MainStringArrayArgument 10 20

 

int 변수 Integer.parseInt("정수로 변환 가능한 문자열");

NumberFormatException

5.6.7 다차원 배열

=>2차원 배열 이상의 배열

수학의 행렬과 같은 자료 구조

 

 

자바는 1차원 배열을 이용해 2차원 배열 구현

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

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

 

세계의 배열 객체를 생성한다.

 

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

 

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

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

scores[0] = new int[2];

scores[1] = new int[3];

 

주의할 점은 정확한 배열의 길이를 알고 인덱스를 사용해야 한다.

ArrayIndexOutOfBoundsException

int [][] scores = {{95, 80} , {92, 96}}

 

 

 

int score = scores[0][0]  ;//95

int score = scores[1][1] ; 96

 

[ ArrayInArrayExample.java]배열 속의 배열

public class ArrayInArrayExample {

           public static void main(String[] args) {

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

                       for (int i = 0; i < mathScores.length; i++) {

                                  for (int k = 0; k < mathScores[i].length; k++) {

                                              System.out.println("mathScores[" + i + "][" + k + "]=" + mathScores[i][k]);

                                  }

                       }

                       System.out.println();

 

                       int[][] englishScores = new int[2][];

                       englishScores[0] = new int[2];

                       englishScores[1] = new int[3];

                       for (int i = 0; i < englishScores.length; i++) {

                                  for (int k = 0; k < englishScores[i].length; k++) {

                                              System.out.println("englishScores[" + i + "][" + k + "]=" + englishScores[i][k]);

                                  }

                       }

                       System.out.println();

 

                       int[][] javaScores = { { 95, 80 }, { 92, 96, 80 } };

                       for (int i = 0; i < javaScores.length; i++) {

                                  for (int k = 0; k < javaScores[i].length; k++) {

                                              System.out.println("javaScores[" + i + "][" + k + "]=" + javaScores[i][k]);

                                  }

                       }

           }

}

 

5.6.8 객체를 참조하는 배열

=>기본 타입(byte, char, short, int, long, float, double, boolean) 배열

각 항목에 직접 값을 가지고 있음

=>참조 타입(클래스, 인터페이스) 배열 - 각 항목에 객체의 번지 가짐

 

 

 

                       String[] strArray = new String[3];

                       strArray[0] = "Java";

                       strArray[1] = "Java";

                       strArray[2] = new String("Java");

 

                       System.out.println(strArray[0] == strArray[1]); //true(같은 객체를 참조)

                       System.out.println(strArray[0] == strArray[2]); //false (다른 객체를 참조)

                       System.out.println(strArray[0].equals(strArray[2]));//true (문자열이 동일)

 

[ArrayReferenceObjectExample.java]객체를 참조하는 배열

public class ArrayReferenceObjectExample {

       public static void main(String[] args) {

               String[] strArray = new String[3];

               strArray[0] = "Java";

               strArray[1] = "Java";

               strArray[2] = new String("Java");

 

               System.out.println(strArray[0] == strArray[1]);

               System.out.println(strArray[0] == strArray[2]);

              System.out.println(strArray[0].equals(strArray[2]));

       }

}

 

5.6.9 배열 복사

배열은 한 번 생성하면 크기 변경 불가

더 많은 저장 공간이 필요하다면 보다 큰 배열을 새로 만들고 이전 배열로부터 항목 값들을 복사

 

=>배열 복사 방법

    • for문 이용
    • System.arrayCopy() 메소드 이용
    • Arrays 클래스 이용

 

[ ArrayCopyByForExample.java]for문으로 배열 복사

public class ArrayCopyByForExample {

           public static void main(String[] args) {

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

                       int[] newIntArray = new int[5];

 

                       for (int i = 0; i < oldIntArray.length; i++) {

                                  newIntArray[i] = oldIntArray[i];

                       }

                      

                       for (int i = 0; i < newIntArray.length; i++) {

                                  System.out.print(newIntArray[i] + ", ");

                       }

           }

}

 

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

얕은 복사 (shallow copy) : 이전 항목이 참조하는 객체와 동일한 객체 참조

깊은 복사 (deep copy) : 참조하는 객체도 별도로 생성

 

[ ArrayCopyExample.java]System.arraycopy()로 배열 복사

public class ArrayCopyExample {

           public static void main(String[] args) {

                       String[] oldStrArray = { "java", "array", "copy" };

                       String[] newSrtArray = new String[5];

 

                       System.arraycopy(oldStrArray, 0, newSrtArray, 0, oldStrArray.length);

 

                       for (int i = 0; i < newSrtArray.length; i++) {

                                  System.out.print(newSrtArray[i] + ", ");

                       }

           }

}

 

5.6.10 향상된 for

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

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

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

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

 

 

[ AdvancedForExample.java]향상된 for

public class AdvancedForExample {

           public static void main(String[] args) {

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

 

                       int sum = 0;

                       for (int score : scores) {

                                  sum = sum + score;

                       }

                       System.out.println("점수 총합 = " + sum);

 

                       double avg = (double) sum / scores.length;

                       System.out.println("점수 평균 = " + avg);

 

           }

}

 

5.7 열거 타입(Enumeration Type)

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

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

 

5.7.1 열거 타입 선언

열거 타입 이름으로 소스 파일(.java) 생성한다.

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

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

Week.java

MemberGrade.java

ProductKind.java

 

열거 타입 선언

 

 

=>한정된 값인 열거 상수 정의

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

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

 

 

 

Package Explorer 뷰에서 프로젝트를 선택한 다음 메뉴에서 [File -> New -> Enum]

 

[ Week.java]열거 타입 선언

public enum Week {

    MONDAY,

    TUESDAY,

    WEDNESDAY,

    THURSDAY,

    FRIDAY,

    SATURDAY,

    SUNDAY

}

 

5.7.2 열거 타입 변수

=>열거 타입 변수 선언

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

 

 

=>열거 상수 값 저장 - 열거 타입 변수값은 열거 상수 중 하나

 

 

 

=>열거 타입 변수는 참조 타입

열거 타입 변수는 참조 타입이므로 null 값 저장 가능

 

 

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

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

 

 

 

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

 

 

 

 

동일한 Week객체를 참조하기 때문이다.

 

 

자바는 컴퓨터의 날짜 및 요일,시간을 프로그램에서 사용할 수 있도록 하기 위해 Date,Calendar, LocalDateTime등의 클래스를 제공한다. LocalDateTime은 자바 8부터 지원하는 API이다.

 

Calendar 변수 선언

Calendar now = Calendar.getInstance();

 

int year = now.get ( Calendar.YEAR ); //

int month = now.get ( Calendar.MONTH ) + 1; //

int day = now.get ( Calendar.DAY_OF_MONTH ); //

int week = now.get(Calendar.DAY_OF_WEEK); //요일(1~7)

int hour = cal.get(Calendar.HOUR_OF_DAY);  //시간

int minute = cal.get(Calendar.MINUTE); //
int second = cal.get(
Calendar.SECOND);//

[
EnumWeekExample.java]열거 타입과 열거 상수

import java.util.Calendar;

 

public class EnumWeekExample {

           public static void main(String[] args) {

                       Week today = null; // 열거 타입 변수 선언

 

                       Calendar cal = Calendar.getInstance();

                       int week = cal.get(Calendar.DAY_OF_WEEK); // (1) ~ (7)까지의 숫자를 리턴

 

                       switch (week) {

                       case 1:

                                  today = Week.SUNDAY;

                                  break;

                       case 2:

                                  today = Week.MONDAY;

                                  break;

                       case 3:

                                  today = Week.TUESDAY;

                                  break;

                       case 4:

                                  today = Week.WEDNESDAY;

                                  break;

                       case 5:

                                  today = Week.THURSDAY;

                                  break;

                       case 6:

                                  today = Week.FRIDAY;

                                  break;

                       case 7:

                                  today = Week.SATURDAY;

                                  break;

                       }

 

                       System.out.println("오늘 요일: " + today);

 

 

 

                       if (today == Week.SUNDAY) {

                                  System.out.println("일요일에는 축구를 합니다.");

                       } else {

                                  System.out.println("열심히 자바 공부합니다.");

                       }

           }

}

 

 

5.7.3 열거 객체의 메소드

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

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

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

 

 

 

=>name() 메소드

name() 메소드는 열거 객체가 가지고 있는 문자열을 리턴한다.

리턴 되는 문자열은 열거 타입을 정의할 때 사용한 상수 이름과 동일하다.

Week today = Week.SUNDAY;
String name = today.name();

 

=>ordinal() 메소드

ordinal() 메소드는 전체 열거 객체 번째 열거 객체인지 알려준다.

Week today = Week.SUNDAY;
int ordinal = today.ordinal();

 

=>compareTo() 메소드

compareTo() 메소드는 매개값으로 주어진 열거 객체를 기준으로 전후로 번째 위치하는지를 비교한다.

만약 열거 객체가 매개값의 열거 객체보다 순번이 빠륻면 음수가 , 순번이 늦다면 양수가 리턴된다.

Week day1 = Week.MONDAY;
Week day2 = Week.WEDNESDAY;
int result1 = day1.compareTo(day2); --> -2
출력
int result 2 = day2.compareTo(day1);-->2
출력

 

=>valueOf() 메소드

valueOf() 메소드는 매개값으로 주어지는 문자열과 동일한 문자열을 가지는 열거 객체를 리턴한다.

Week weekDay = Week.valueOf("SATURDAY");

 

=>values() 메소드

values() 메소드는 열거 타입의 모든 열거 객체들을 배열로 만들어 리턴한다.

Week[] days = Week.values();

for(Week day : days) {

            System.out.println(day);

        }

 

배열의 인덱스는 열거 객체의 순번과 같고 각 인덱스 값은 해당 순법의 열거 객체 번지이다.

 

 

[ EnumMethodExample.java]열거 객체의 메소드

public class EnumMethodExample {

       public static void main(String[] args) {

               // name() 메소드

               Week today = Week.SUNDAY;

               String name = today.name();

               System.out.println(name); // SUNDAY

 

               // ordinal() 메소드

               int ordinal = today.ordinal();

               System.out.println(ordinal); // 6

 

               // compareTo() 메소드

               Week day1 = Week.MONDAY;

               Week day2 = Week.WEDNESDAY;

               int result1 = day1.compareTo(day2);

               int result2 = day2.compareTo(day1);

               System.out.println(result1); // -2

               System.out.println(result2); // 2

 

               // valueOf() 메소드

               /*

                * Week weekDay = Week.valueOf("SUNDAY");

                * if(weekDay == Week.SATURDAY

                * || weekDay == Week.SUNDAY) {

                * System.out.println("주말 이군요");

                * } else {

                * System.out.println("평일 이군요"); }

                */

 

               if (args.length == 1) {

                      String strDay = args[0];

                      Week weekDay = Week.valueOf(strDay);

                      if (weekDay == Week.SATURDAY || weekDay == Week.SUNDAY) {

                             System.out.println("주말 이군요");

                      } else {

                             System.out.println("평일 이군요");

                      }

               }

 

               // values() 메소드

               Week[] days = Week.values();

               for (Week day : days) {

                      System.out.println(day);

               }

       }

}

 

연습문제

1. 참조 타입에 대한 설명으로 틀린 것은 무엇입니까? (4)

 

1. 참조 타입에는 배열 , 열거 , 클래스 , 인터페이스가 있다.

2. 참조 타입 변수의 메모리 생성 위치는 스택이다.

3. 참조 타입에서 ==,!= 연산자는 객체 번지를 비교한다.

4. 참조 타입은 null 값으로 초기화할 수 없다.

 

2. 자바에서 메모리 사용에 대한 설명으로 틀린 것은 무엇입니까? (3)

 

1. 로컬 변수는 스택 영역에 생성되며 실행 블록이 끝나면 소멸된다.

2. 메소드 코드 , 상수 , 열거 상수는 정적(메소드) 영역에 생성된다.

3. 참조되지 않는 객체는 프로그램에서 직접 소멸 코드를 작성하는 것이 좋다.

4. 배열 및 객체는 힙 영역에 생성된다.

 

3. 자바에서는 사용자가 직접소멸코드를 작성할수 없다.

 

3. String 타입에 대한 설명으로 틀린 것은 무엇입니까? (2)

 

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

2. String 타입의 문자열 비교는 == 를 사용해야 한다.

3. 동일한 문자열 리터럴을 저장하는 변수는 동일한 String 객체를 참조한다.

4. new String ("문자열")은 문자열이 동일하더라도 다른 String 객체를 생성한다.

 

2. String 타입의 문자열 비교는 equals( ) 를 사용해야 한다.

 

4. 배열을 생성하는 방법으로 틀린 것은 무엇입니까? (2)

 

1. int[]array = {1,2,3};

2. int[]array;araay = {1,2,3};

3. int[]araay = new int[3];

4. int[][]array = new int[3][2];

 

5. 배열의 기본 초기값에 대한 설명으로 틀린 것은 무엇입니까? (3)

 

1. 정수 타입 배열 항목의 기본 초기값은 0 이다.

2. 실수 타입 배열 항목의 기본 초기값은 0.0f 또는 0.0 이다.

3. boolean 타입 배열 항목의 기본 초기값은 true 이다.

4. 참조 타입 배열 항목의 기본 초기값은 null 이다.

 

3. boolean 타입 배열 항목의 기본 초기값은 false 이다.

 

6. 배열의 길이에 대한 문제입니다. array.length 의 값과 array[2].length 의 값은 얼마입니까?

 

int[][] array = {

{95,86},

{83,92,96},

{78,83,93,87,88}

};

 

array.length -> (3)

array[2].length -> (5)

 

7. 주어진 배열의 항목에서 최대값을 구해보세요 (for문을 이용하세요).

package sec5_example;

 

public class Exercise07 {

    public static void main(String[] args) {

        int max = 0;

        int[] array = {1,5,3,8,2};

        for (int i = 0; i < array.length; i++) {

            if(max<array[i]) {

                max = array[i];

            }

        }

        System.out.println("max: " + max);

    }

}

 

max: 8

 

8. 주어진 배열의 전체 항목의 합과 평균값을 구해보세요(중첩 for문을 이용하세요.)

import java.lang.reflect.Array;

 

public class Exercise08 {

    public static void main(String[] args) {

        int[][] arry = {

                {95,86},

                {83,92,96},

                {78,83,93,87,88}

        };

        

        int sum = 0;

        double avg =0.0;

        int count = 0;

        

        for (int i = 0; i < arry.length; i++) {

            for (int j = 0; j < arry[i].length; j++) {

                sum += arry[i][j];

                count++;

            }

        }

        avg=(double)sum/count;

        

        System.out.println("sum: " + sum);

        System.out.println("avg: " + avg);

    }

}

sum: 881

avg: 88.1

 

 

9. 다음은 키보드로부터 학생 수와 각 학생들의 점수를 입력받아서, 최고 점수 및 평균 점수를 구하는 프로그램입니다. 실행 결과를 보고, 알맞게 작성해보세요(참고로 16라인에서 Scanner nextInt () 메소드는 콘솔에 입력된 숫자를 읽고 리턴합니다).

package sec5_example;

 

import java.util.Scanner;

 

public class Exercise09 {

    public static void main(String[] args) {

        boolean run = true;

        int studentNum = 0;

        int[] scores = null;

        Scanner scanner = new Scanner(System.in);

        

        while(run) {

            System.out.println("--------------------");

            System.out.println("1.학생수 | 2.점수입력 | 3.점수리스트 | 4.분석 | 5.종료");

            System.out.println("--------------------");

            System.out.print("선택>");

            

            int selectNo = scanner.nextInt();

            

            if(selectNo ==1) {

                System.out.print("학생수>");

                studentNum = scanner.nextInt();

                scores = new int[studentNum];

            } else if(selectNo ==2) {

                for (int i = 0; i <studentNum; i++) {

                    System.out.print("scores["+i+"]>");

                    int score=scanner.nextInt();

                    scores[i] = score;

                }

            } else if(selectNo ==3) {

                for(int i=0;i<studentNum;i++) {

                System.out.println("score[" + i +"]:" + scores[i]);

                }

            } else if(selectNo ==4) {

                int sum = 0;

                int max = 0;

                double avg = 0;

                for(int i=0;i<studentNum;i++) {

                    sum+=scores[i];

                    if(max<scores[i]) {

                        max=scores[i];

                    }

                }

                avg = sum/studentNum;

                System.out.println("최고 점수:" + max);

                System.out.println("평균 점수:" + avg);

                

            } else if(selectNo ==5) {

                run = false;

            }

        }

        System.out.println("프로그램 종료");

    }

 

}

 

 

 

반응형

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

07. 상속  (0) 2020.09.29
06. 클래스  (0) 2020.09.28
04. 조건문과 반복문  (0) 2020.09.26
03. 연산자  (0) 2020.09.24
02.변수와 타입  (1) 2020.09.22

+ Recent posts