06-2 / 필드

  • 필드의 정의

필드는 객체의 고유 데이터, 객체가 가져야 할 부품, 객체의 현재상태 데이터를 저장하는 곳이다. 

클래스를 설계할 때 이 정보들은 필드로 선언되어야 한다.

 


필드 선언) 

필드 선언은 클래스 중괄호 {} 블록 어디서든 존재 가능하다.

생성자와 메소드와의 순서도 상관없지만 생성자와 메소드 {} 블록 안에서 선언 될 수는 없다. 

생성자와 메소드 {} 블록 안에서 생성된 건 로컬 변수가 되기 때문

타입 필드 [= 초기 값]; // [] 안에 것은 선택사항

String name = "littlezero";
int code = 48;
boolean Start;

 타입은 필드에 저장할 데이터 종류를 결정하고 타입에는 기본타입, 참조타입 모두 가능하다.

 

초기값이 설정되지 않은 필드는 객체 생성 시 자동으로 기본 초기값으로 설정

분류 타입 초기값
기본 타입 정수 타입 byte 0
char \u0000 (빈 공백)
short 0
int 0
long 0L
실수 타입 float 0.0F
double 0.0
논리 타입 boolean false
참조 타입 배열 null
클래스(String 포함) null
인터페이스 null

 

 


필드 사용) 

필드값을 읽고 변경하는 것을 필드 사용이라 한다. 

클래스 내부의 생성자나 메소드가 필드를 읽고 변경하는 것은 단순하게 되지만, 클래스 외부에서 사용하려면 우선적으로 객체를 생성 후 필드를 사용해야 한다. 왜냐하면 객체가 생성되지 않았다면 필드 역시 존재하지 않기 때문이다.

Car myCar = new Car();
myCar.speed = 60;

// 객체를 먼저 선언
// 객체에 도트 연산자를 사용해 필드에 접근하여 읽기와 변경하기가 가능

 

 

* 발표용이라 비유로 표현한 게 많습니다. 

 

06-1 / 객체 지향 프로그래밍

  • 객체의 정의

객체란 자신의 속성을 가지고 있으면서 식별 가능한 것 (물리적, 추상적 모두)

나라는 사람의 객체가 존재한다면 아래와 같은 속성과 동작으로 구성되어 있고

속성 나의 이름, 나의 성별, 나의 나이 등 자바 필드(field)
동작 코딩하다,  졸다, 공부하다 등 메소드(method)

 

현실 세계의 객체를 가지고 소프트웨어 객체로 설계 객체 모델링 (object modeling)이라고 한다.

 배열 [] 필드 (속성) length 배열의 길이
메소드 (동작) sort() 배열을 정렬하다

 


객체의 상호작용) 

현실에서도 소프트웨어에서도 객체끼리는 서로 상호 작용한다. 그리고 이런 상호작용의 수단이 바로 메소드

객체가 다른 객체의 기능을 이용하는 것이 바로 메소드 호출.

 (ex. 누군가 나에게 편의점에 다녀와 라고 시켰다면 메소드 호출)

 

메소드 호출 형식은 다음과 같다.

리턴값 = 객체.메소드(매개값1, 매개값2, ...);

① 객체에 도트(.) 연산자를 붙이고 메소드 이름을 작성한다. 도트 연산자는 객체의 필드와 메소드에 접근할 때 사용

② 매개값은 메소드를 실행하기 위해 필요한 데이터 

③ 리턴 값은 메소드가 실행되고 난 후 호출한 곳으로 돌려주는 값

int result = Calculator.add(10,20);
System.out.println(result);
// 30 (리턴값)

 

 

 


객체 간의 관계) 

객체는 개별적으로 사용도 가능하지만 대부분 다른 객체와 관계를 맺고 있다.

집합관계 집합관계에 있는 객체 중 하나는 부품 하나는 완성품
(ex. 프로젝트에서 각자가 만든 코드들은 부품, 모두 합친걸 완성품이라 할때 이 둘의 관계는 집합 관계라 할 수 있다.
사용관계 객체 간의 상호작용.  다른 객체의 메소드를 호출하여 원하는 결과를 얻어낸다.
(ex. B반 담임 매니저님께 질문을 한다 (사용관계)
       E반 담임 매니저님께 질문은 불가능하다 (사용관계x)
상속관계 상위(부모) 객체를 기반으로 하위(자식) 객체를 생성하는 관계.
일반적으로 상위객체는 종류, 하위 객체는 구체적인 사물
(ex. 하위 -> 나와 팀원 - 그라우해 스터디팀 - B반 - 항해99 -> 상위

 

 

  • 객체 지향 프로그래밍 정의

만들고자 하는 완성품인 객체를 모델링하고, 집합관계에 있는 부품 객체와 사용관계에 있는 객체를 하나씩 설계한 후 조립하는 방식으로 프로그램을 개발하는 기법

 

 

 


객체와 클래스) 

객체를 만들기 위한 설계도를 클래스(Class)라고 한다. 클래스에는 객체를 생성하기 위한 필드와 메소드가 정의 되어 있다. 클래스로부터 만들어진 객체를 해당 클래스의 인스턴스(Instance)라고 한다. 

하나의 클래스로 여러 인스턴스를 만들 수 있는데 하나의 설계도로 자동차 여러대를 만드는 것과 같다.

 

객체 지향 프로그래밍 개발 3단계

1. 클래스 설계

2. 설계된 클래스로 객체 생성

3. 생성된 객체 이용

 

+ main메소드가 없는 클래스는 객체 생성 과정을 거처 사용

 

 

 


클래스 선언) 

설계도인 클래스에 이름을 정하여 사용하는데 이름에도 규칙이 있다.

- 하나 이상의 문자

- 첫 글자에는 숫자 불가

- $ , _ 외의 특수문자 불가

- 자바 키워드 사용 불가

 

자바언어는 대소문자를 구분하기때문에 클래스 이름도 대소문자를 구분한다.

통상적으로 클래스는 단일 단어 경우 첫글자 대문자에 나머지 소문자

단어가 혼합되어 있다면 각 단어의 첫글자는 대문자로 작성

(ex. String, ArrayList, Caculator 등)

 

클래스 이름을 정했다면 '클래스이름.java'로 소스 파일(프로그래머가 작성한 코드파일)을 생성.

소스파일도 대소문자 구분하여 클래스 이름과 동일하게 생성한다.

 

보통 소스 파일당 클래스는 하나 선언하지만 2개 이상의 클래스도 선언 가능하다

public class Car {
}

class Tier {
}

클래스가 2개 이상 선언된 소스 파일은 컴파일하면 바이트 코드 파일(.class)가 클래스 선언 개수만큼 생긴다. 결국 소스파일은 클래스 선언을 담고 있는 저장 단위일 뿐, 클래스 자체는 아님.

 

+ public 접근 제한자 : public 접근 제한자는 파일 이름과 동일한 이름의 클래스 선언에만 붙일 수 있다.

가급적이면 소스 파일 하나당 동일한 이름의 클래스 하나를 선언하는 것이 좋다

 

 

 


객체 생성과 클래스 변수) 

클래스 선언후 컴파일을 했다면 설계도가 만들어 졌다.

이 클래스에서 객체를 생성하려면 다음과 같이 new 연산자를 사용하면 된다.

클래스 변수; 
변수 = new 클래스();

//------------------------- 위아래 동일

클래스 변수 = new 클래스();

 

new 는 클래스로부터 객체를 생성시키는 연산자이다. 

new 뒤에는 생성자가 오는데 클래스 () 형태이며 new연산자로 생성된 객체는 메모리 힙 영역에 생성된다.

 

객체 지향 프로그램에서는 메모리 내에서 생성된 객체의 위치를 모르면 객체를 사용할 수 없다.  그래서 new 연산자는 힙 영역에 객체를 생성시킨 후 객체의 번지를 리턴한다. 이 주소를 참조 타입인 클래스 변수에 저장해두면 변수를 통해 객체를 사용할 수 있다.

 

아래는 같은 클래스로부터 생성되었지만 new 연산자를 사용한 만큼 객체가 메모리에 생성되어 각각의 객체로 고유한 데이터를 가지고 메모리에서 활동하게 된다.

ArrayList<Integer> arr = new ArrayList<Integer>();
ArrayList<Integer> arr1 = new ArrayList<Integer>();

 

클래스의 용도 2가지

라이브러리용 라이브러리 클래스는 다른 클래스에서 이용할 목적으로 설계 실행용 제외 나머지 모두
실행용 실행 클래스는 프로그램의 실행 진입점인 main() 메소드를 제공하는 역할  프로그램 전체에서 하나

 

아래처럼 라이브러리인 동시에 실행 클래스로 만들수도 있다. (하지만 보통은 분리해서 쓴다)

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

 

 


클래스의 구성 멤버) 

클래스에는 객체가 가져야 할 구성 멤버가 선언된다.

public class ClassName {
	
    int fieldname; // 필드
    ClassName() {...} // 생성자
    void methodName() {...} // 메소드
}
필드
(field)
객체의 고유 데이터, 부품 객체, 상태 정보 저장
선언되는 형태는 변수와 비슷하나 필드를 변수라고 하지 않는다. 
변수는 메소드 내에서만 사용되고 생성자와 메소드 실행 종료시 수명을 다하지만
필드는 생성자와 메소드 전체에 사용되며 객체가 소멸되지 않는 한 객체와 존재한다.
생성자
(contructor)
생성자는 new 연산자로 호출되는 중괄호 {} 블록. 
역할은 객체 생성시 초기화 담당. 필드를 초기화 하거나 메소드를 호출해서 객체를 사용할 준비를 한다. 
생성자는 메소드와 비슷하게 생겼지만. 클래스 이름으로 되어 있고 리턴 타입이 없다. 
메소드
(method)
객체 동작에 해당하는 중괄호 {} 블록.
이 블록은 이름을 가지는데 이것이 메소드의 이름이다. 메소드를 호출하면 {} 안 모든 코드들이 일괄적으로 실행
필드를 읽고 수정하는 역할도 하지만, 다른 객체를 생성해 다양한 기능을 수행하기도
객체 간의 데이터를 전달하는 수단이며 외부로 부터 매개 값을 받아 실행에 이용하고, 실행 후 외부로 리턴할 수도 있다.

 

 

 

------- 1편 포스팅에 이어서

 

다차원 배열) 

행과 열로서 구성되 배열을 2차원 배열이라고 한다. 행과 열로 구성되어 있기 때문에 가로 인덱스와 세로인덱스를 사용한다.

자바는 2차원 배열을 중첩 배열 방식으로 구현하기위해 다음과 같은 코드를 사용한다.

ex. 2행 3열의 배열)
int[ ][ ] first = new int[2][3]

이 코드는 메모리에 3가지 배열 객체를 생성한다.

스택에 참조되는 1번째 배열 객체는 ① 부분을 생각하면 된다. 행의 수만큼 길이의 배열이 생성되며 각 인덱스에 각 행에 대한 배열 객체의 주소(=번지)를 갖는다. 

그리고 그렇게 연결된 각 객체들은 동일한 길이 또는 각각 다른 길이의 배열을 갖고 각 인덱스마다 값을 갖는다..

배열의 길이는 다음 처럼 볼 수 있다.

int[][] first = {{1,2,3},{4,5,6}};

System.out.println(first.length);	// 2 행의 수
System.out.println(first[0].length);	// 3 인덱스 0번의 열의 수
System.out.println(first[1].length);	// 3 인덱스 1번의 열의 수

그럼 2번째 행의 3번째 값을 알고 싶다면 어떻게 해야할까

2번째 행은 인덱스 1번에 위치하고, 3번째는 인덱스 2번에 위치한다

따라서 

first[1][2] 이렇게 순서대로 넣어 값인 6을 읽을 수 있다.

 

 

 

 

비유 ? (조금더 잘 정리해야할 거 같다)

더보기

학생이름을 정리할 목적의 1학년이라는 이름의 다차원 배열이 있다고 하자. (반이름은 임의로 붙인것)

1학년이라는 변수가 처음으로 참조하는 배열 객체 길이는 반의 개수(행의 수)만큼이고 각 칸에 반의 이름(객체주소)이 적혀있다. ①

첫번째 칸의 반 이름을 따라 A반에 가보면 A반 이름이 번호 순서대로 배열되어 있다. ②

두번째 칸의 반 이름을 따라 B반에 가보면 B반 이름이 번호 순서대로 배열되어 있다. 

 

A반과 B반 인원수가 다른것도 가능하다.

 

이 1학년 배열에 대해 length를 물어보게 되면

 

1학년.length는 2라고 대답할 것이다. A반, B반 2개가 존재하기 때문

그러면 1학년[0].length를 물으면 3이라고 대답할 것이다. 1학년 배열 0번에는 A반이 연결되어 있고 A반에 1,2,3 3명이 존재하기 때문

1학년[1].length를 물어도 3이라고 대답할 거다. 다만 이번엔 B반과 연결되어 있고 B반에 4,5,6 3명이 존재하기 때문에 3명이라 답하는 거다.

 

그럼 B반의 3번째 친구 이름을 알고 싶다면 어떻게 해야할까

B반은 반들 중 인덱스 1번에 위치하고, B반 인원수 중 3번째는 인덱스 2번에 위치한다

따라서 

first[1][2] 이렇게 순서대로 넣어 값인 6을 읽을 수 있다.

 

 

다차원 배열은 다음과 같이 3가지 방법으로 선언할 수 있으며 반복문에서는 아래같이 사용 가능하다.

int[][] mathScores = new int[2][3]; 	// 행과 열 선언

int[][] englishScores = new int[2]; 	// 행 수만 먼저 선언
englishScores[0] = new int[2]; 		// 열 선언
englishScores[1] = new int[3];

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]);
    }
}

 

 


객체를 참조하는 배열) 

기본 타입의 배열은 각 항목의 직접 값을 가지고 있지만, 참조타입 배열은 항목에 객체의 번지를 가지고 있다. 

배열에 넣었다 하더라도 비교하는 방식이 바뀌는 건 아닌것이다. 따라서  == 연산자가 동일한 값이 아닌 동일한 객체인지 판별하는 연산인 것도 동일하며 String[] 배열도 각각 String 객체의 번지 값을 가지고 있기 때문에 문자열 비교를 위해 기존 String클래스가 하는 방법처럼  equals() 메소드를 사용해야 한다. 

 

 


배열 복사) 

배열은 한번 생성하면 크기를 변경할 수 없기 때문에 더 많이 저장하려면 더 큰 배열을 만들고 배열 값을 복사해 넣어줘야 한다.

 

1. for문으로 복사

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.println(newIntArray[i]);
}
// 1, 2, 3, 0, 0

값이 넘어가지 않은 나머지 부분은 초기값으로 유지된다.

 

 

2. System.arraycopy() 메소드로 복사

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

System.arraycopy(oldIntArray, 0, newIntArray, 0, oldIntArray.length);

for(int i=0; i< newIntArray.length; i++){
    System.out.println(newIntArray[i]);
}
// 1, 2, 3, 0, 0
System.arraycopy( oldIntArray, 0, newIntArray, 0, oldIntArray.length );
  원본 배열 복사할
시작 인덱스
새로운 배열 복사 받을
시작 인덱스
복사할 개수  

 

 

 


for-each문) 

자바는 배열이나 컬렉션을 좀 더 쉽게 처리하기 위해 향상된 for문을 제공한다.

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

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

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

double avg = (double) sum/ scores.length;
System.out.println("점수평균 : "+avg);
for ( int score : scores  ) { ③ 실행문 }
① 배열에서 가져오는 값이 대입될 변수 : ② 대상 배열

 

for-each문 실행 흐름은

1. for문 실행시 ②대상배열에서 가져올 값이 있는 지 판단한다.

2. 값이 존재하면 그 값을 ①변수에 대입한다. (값이 없다면 종료한다.)

3. ③실행문을 실행한다.

4. ③실행문이 모두 실행됬다면 다시 1번으로 돌아간다. 

 

 

Chapter 05-2 확인문제

 

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

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

// 작성위치

System.out.println(max);
더보기
int max = 0;
int[] array = {1, 5, 3, 8, 2};

for(int i : array){
    if(i > max){
        max = i;
    }
}

System.out.println(max);

 

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

int[][] array = {
        {95, 86},
        {83, 92, 96},
        {78, 83, 93, 87, 88}
};

int sum = 0;
double avg = 0.0;

// 작성위치

System.out.println("sum : "+sum);
System.out.println("avg : "+avg);
더보기
int[][] array = {
        {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< array.length; i++){
    for(int k=0; k <array[i].length; k++){
        sum += array [i][k];
        count++;
    }
}
avg = (double) sum / count;

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

// sum : 881
// avg : 88.1

 

6. 키보드로 부터 학생 수와 각 학생들의 점수를 입력받아서, 최고 접수 및 평균 점수를 구하는 프로그램입니다. 실행 결과를 보고 알맞게 작성해보세요.

   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.println("선택>");
            
            int selectNo = Integer.parseInt(scanner.nextLine());
            
            if(selectNo == 1){
                //작성위치
            } else if (selectNo == 2){
                //작성위치
            } else if (selectNo == 3){
                //작성위치
            } else if (selectNo == 4){
                //작성위치
            } else if (selectNo == 5) {
                run = false;
            }
        }

        System.out.println("프로그램 종료");
    }
    
--------------------------------------------------------
//1.학생수 | 2.점수입력 | 3. 점수리스트 | 4. 분석 | 5. 종료
//--------------------------------------------------------
//선택>
//1
//학생수>
//3
//--------------------------------------------------------
//1.학생수 | 2.점수입력 | 3. 점수리스트 | 4. 분석 | 5. 종료
//--------------------------------------------------------
//선택>
//2
//score[0]>
//88
//score[1]>
//95
//score[2]>
//79
//--------------------------------------------------------
//1.학생수 | 2.점수입력 | 3. 점수리스트 | 4. 분석 | 5. 종료
//--------------------------------------------------------
//선택>
//3
//score[0]>88
//score[1]>95
//score[2]>79
//--------------------------------------------------------
//1.학생수 | 2.점수입력 | 3. 점수리스트 | 4. 분석 | 5. 종료
//--------------------------------------------------------
//선택>
//4
//최고 점수 : 95
//평균 점수 : 87.33333333333333
//--------------------------------------------------------
//1.학생수 | 2.점수입력 | 3. 점수리스트 | 4. 분석 | 5. 종료
//--------------------------------------------------------
//선택>
//5
//프로그램 종료
더보기
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.println("선택>");

        int selectNo = Integer.parseInt(scanner.nextLine());

        if(selectNo == 1){
            System.out.println("학생수>");
            studentNum = Integer.parseInt(scanner.nextLine());
        } else if (selectNo == 2){
            scores = new int[studentNum];
            for(int i=0; i<scores.length; i++){
                System.out.println("score["+i+"]>");
                scores[i] = Integer.parseInt(scanner.nextLine());
            }
        } else if (selectNo == 3){
            for(int i=0; i<scores.length; i++){
                System.out.println("score["+i+"]>" + scores[i]);
            }
        } else if (selectNo == 4){
            int max = 0;
            int sum = 0;
            for(int i=0; i<scores.length; i++){
                sum += scores[i];
                if(scores[i]>max){
                    max = scores[i];
                }
            }
            double avg = (double) sum / scores.length;
            System.out.println("최고 점수 : " + max);
            System.out.println("평균 점수 : " + avg);
        } else if (selectNo == 5) {
            run = false;
        }
    }

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

 

 

 

 


05-3 / 열거타입

열거타입은 한정된 값인 열거 상수(enumeration constant) 중에서 하나의 상수를 저장하는 타입이다. 

 

열거타입 선언) 

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

열거 타입 이름은 관례적으로 첫글자는 대문자 나머지로 소문자 구성하며 여러단어일 경우 각 단어 첫글자는 대문자로 하는 것이 관례.

ex. MemberGrade.java , ProductKind.java

 

열거타입 선언 키워드는 public enum으로 반드시 소문자로 작성해야한다. 그리고 열거 타입 이름은 소스파일 이름과 대소문자가 모두 일치해야 한다.

 

그리고 열거 상수는 모두 대문자로 작성하는 것이 관례다.

열거 상수가 여러 단어로 구성될 경우에는 단어 사이 _로 연결하는 것이 관례

 

 

열거 타입 변수) 

열거 타입을 선언했다면 ,  열거 타입 변수를 선언하는 방법은 아래와 같다

Week now;			// 열거 타입 변수 선언
Week today = Week.Sunday;	// 열거 상수 저장
Week birthday = null;		// 열거타입도 참조타입이다.

 

열거 상수 또한 객체로 생성되기 때문에 열거 타입 또한 참조 타입 변수이다.

열거 상수 7개로 선언한 Week 변수는 Monday부터 Sunday까지 총 7개의 객체를 생성하게 된다. 그리고 메소드 영역에 생성된 열거 상수가 해당 Week 객체를 각각 참조하게 된다.

 

Week today = Week.Sunday;

열거타입 변수는 today는 스택 영역에서 생성된다. today에 저장되는 값은 Week.SUNDAY 열거 상수가 참조하는 객체의 번지를 복사한 값이다. 따라서 열거 상수 Week.SUNDAY와 today변수는 서로 같은 Week 객체를 참조하게 된다. 그래서 둘을 == 연산 하게 되면 true 결과가 나온다.

 

열거 타입 Week를 이용해 보려면 날짜 정보가 필요하다.

자바는 Calendar 클래스를 통해 컴퓨터의 날짜, 요일, 시간을 제공한다. 

import java.util.Calendar;

public class chap01 {
    public static void main(String[] args) {

        Calendar now = Calendar.getInstance();

        int year = now.get(Calendar.YEAR);
        int month = now.get(Calendar.MONTH);
        int day = now.get(Calendar.DAY_OF_MONTH);
        int week = now.get(Calendar.WEEK_OF_MONTH);
        int hour = now.get(Calendar.HOUR);
        int minute = now.get(Calendar.MINUTE);
        int second = now.get(Calendar.SECOND);
    }
}

 

이를 통해 오늘 요일을 얻는 예시

import java.util.Calendar;

public class chap01 {
    public static void main(String[] args) {

        Week today = null;

        Calendar now = Calendar.getInstance();

        int week = now.get(Calendar.DAY_OF_WEEK);

        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("열심히 자바 공부를 합니다.");
        }
    }
}
// 오늘 요일 : SATURDAY
// 열심히 자바 공부를 합니다.

 

 

 

 

+질문
* 열거상수 객체가 생성되는 시점. 열거타입 변수를 생성할때? 아니면 빌드 되면서 메소드 영역에 열거상수 저장될 때?
- 열거 타입도 static 타입이기 때문에 변수 선언시 생성되는 게 아니라 빌드 될때 생성된다.
* 만약 열거타입 변수가 참조를 끊더라도 열거 상수 같은 경우는 메소드 영역에서 참조되고 있으므로 가비지 콜렉터가 제거하는 대상에서 제외되나?
- 가비지 콜렉터는 Heap영역에서만 활동한다. 메소드영역이나 스택영역에서는 가비지 콜렉터가 활동하지 않으므로 열거타입은 대상이 되지않는다.

 

 

 

05-1 / 참조 타입과 참조 변수

자바의 타입은 크게 기본 타입(Primitive Type)과 참조 타입(Reference Type)으로 분류된다.

기본 타입은 이 포스팅에서 정리 (https://littlezero48.tistory.com/93) 한 것처럼 정수, 실수, 문자, 논리 리터럴을 저장하는 타입을 말하고

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

 

 

기본 타입과 참조 타입) 

기본타입 선언 변수와 참조타입 선언 변수의 차이점은 저장되는 값이다. 

기본타입의 변수를 실제 값을 변수에 저장하지만, 참조타입의 변수는 메모리 번지를 변수안에 저장한다.

번지를 통해 객체를 참조한다는 뜻에서 참조 타입이라 명명되었다.

 

다음과 같은 변수들이 있다.

// 기본타입
int a = 100;
double b = 200.0;

// 참조타입
String c = "스트링"
String d = "참조타입"

기본타입 변수와 참조타입 변수가 생성되는 스택에서 이 변수 값들을 보면 

(참고로 숫자는 예시)

a 100
b 200.0
c 100
d 200

이 들어있다. 

a와 b는 분명 내가 넣은 값인데 c와 b는 넣지 않은 이상한 값이 들어있다. 이 값은 무엇일까? 바로 이 값이 변수들의 값을 가지고 있는 String 객체의 주소 즉, 번지들이다.

 

 

 

 


메모리 사용 영역) 

그럼 스택은 뭐고 변수들이 참조한다는 번지는 어디의 번지일까?

이를 알려면 JVM이 운영체제로 부터 할당받아 사용하는 메모리 영역인 Runtime Data Area에 대해서 알아야한다.

출처:&nbsp;https://www.freecodecamp.org/news/jvm-tutorial-java-virtual-machine-architecture-explained-for-beginners/

 

이 중 참조 변수에 대해 알려면 우선 3영역을 알아보자

Method Area (=Class Area =Static Area)
이 영역은 JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역이다.
JVM이 뭔가를 실행하기 위해서는 먼저 바이트 코드들이 메모리 공간에 저장되어야 한다.
이를 위해 먼저 컴파일된 클래스(~.class) 파일들의 바이트 코드를 클래스 로더로 읽어들여 메소드 영역에 올리는데 이를 클래스 로딩이라고 하며 이후 메인 메소드를 호출하는 것으로 부터 시작한다. 메인 메소드를 호출하면 우리가 항상 메인 메소드에 쓰는 클래스와 static변수가 있는데 이게 바로 이 영역에 올라오게 되는 것이다.

메소드 영역에 바이트 코드들이 올라오게 되면 클래스별로 정적필드(static field), 상수(constant), 메소드 코드, 생성자(constructor) 코드 등으로 분류해서 저장한다.

참조 : (클래스 로딩 절차까지 소개) https://blog.wanzargen.me/16
Heap Area
힙 영역은 객체와 배열이 생성되는 영역이다. 다른 객체의 필드 나 JVM Stack Area의 변수가 참조하는 객체와 배열들이 위치한 곳이다. 
만약 이곳의 객체나 배열 중 참조되지 못하고 덩그러니 남아있는 객체는 쓰레기로 취급되며 Garbage Collector를 실행시켜 자동으로 제거한다. 따라서 개발자가 직접 제거하는 일은 없다.
Stack Area
JVM 스택은
메소드를 호출할때 마다 메소드 상태를 저장하기위한 Frame을 생성(push)하고
메소드가 종료되면 해당 Frame을 제거(pop)하는 동작을 수행한다.

이렇게 스택안에 생성되는 Frame 안에는 로컬 변수 스택이 있는데 여기에 기본타입 변수나 참조타입 변수가 push되거나 pop된다.

스택 영역에 변수가 생성되는 시점은 변수 초기화 때로 최초로 변수에 값이 저장될 때 이며, 로컬 변수가 영향력을 발휘하는 블록내에서만 스택에 존재하고 블록을 벗어나면 pop된다.

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

 

 

 

 


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

기본타입 변수에서는 ==는 값이 같다, !=는 값이 다르다 의 단순한 논리로 정리되지만 

참조타입 변수에서는 ==가 동일한 객체인지(= 동일한 힙 번지 값을 가지는 것인지), !=는 동일한 객체가 아닌지 (= 다른 힙번지 값을 사용하는지)를 판별할 때 사용한다.

 

 

 

 

 


null 과 NullPointerException) 

 

* null

참조타입 변수는 힙 영역의 객체를 참조하지 않는 다는 뜻으로 null 값을 갖는다.

하지만 이 null 값 자체도 초기값으로 사용할 수 있기 때문에 null로 초기화된 함수 또한 stack 영역에 push된다.

null값인지 아닌지는 판별하는 것은 == null 과 != null 로 할 수 있다.

 

뿐만 아니라 이전에 다른 객체를 참조한 변수에 null 값을 넣어주어 더 이상 객체를 참조하지 않게 할 수 있다.

+ 참고로 참조를 잃은 객체는 jvm이 gabage collector을 구동시켜 메모리에서 제거한다.

 

 

* NullPointerException

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

참조변수에서 가장 많이 발생하는 예외 중 하나가 바로 NullPointerException 인데, 이 예외는 참조타입 변수를 잘못 사용 하면 발생한다. 

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

String str = null;
System.out.println(str.length());
// NullPointerException

 변수 이름만 스택에 올라와 있을 뿐 예외 이름처럼 null은 아무것도 가르키고 있지 않기 때문에 값을 넣을 수도 그것으로 길이를 알수도 없다.

 

 


String 타입) 

String a = "스트링";

String 변수에 문자열을 저장한다고 표현하지만 엄밀히 말해서는 틀린말이다. 

String 객체가 생성되어 문자열을 저장하고 String 변수에는 그 String 객체 번지가 저장되는 것이기 때문 하지만 일반적으로는 String변수에 문자열을 저장한다고 한다.

 

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

String a = "객체";
String b = "객체";

System.out.println(System.identityHashCode(a));  // 객체번지 조회함수
System.out.println(System.identityHashCode(b));

if(a == b){
    System.out.println("일치");
} else {
    System.out.println("불일치");
}
// 1854778591
// 1854778591
// 일치

 

만약 같은 문자열 리터럴이더라도 다른 객체를 공유하게 할 수도 있는데 new 연산자를 사용해 String 객체를 생성하면 된다. 이와 같이 new 연산자는 힙 영역에 새로운 객체를 만들때 사용하는 객체 생성 연산자라고 한다.

만약 둘다 new 연산자로 새로운 객체를 만들었다면 그건 또 각각의 힙 영역에 새로운 객체를 따로 만들었기에 또 다른 객체가 된다.

String a = "객체";
String b = new String("객체");

System.out.println(System.identityHashCode(a));  // 객체번지 조회함수
System.out.println(System.identityHashCode(b));

if(a == b){
    System.out.println("일치");
} else {
    System.out.println("불일치");
}
// 1854778591
// 2054798982
// 불일치

 

만약 String 변수끼리 번지수 비교가 아니라 값 그자체를 비교하고 싶다면 equals() 메소드를 사용해야한다. 

String a = "객체";
String b = new String("객체");

if(a.equals(b)){
    System.out.println("일치");
} else {
    System.out.println("불일치");
}
// 일치

 

 


05-2 / 배열

배열이란?) 

변수는 하나에 한개의 데이터만을 저장할 수 있지만 배열은 여러 데이터를  적은 코드로 쉽게 다룰수있게 한다.

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

  index 0 1 2 3  
score[]  = [ 10, 20, 30, 40 ];

 

배열의 각 인덱스는 각 항목 데이터를 읽거나 저장할때 사용하며 인덱스 번호를  []안에 넣어 사용한다.

int[] score = [10,20,30,40]
System.out.println(score[0]);
// 10

 

* 배열의 특징 )

- 같은 타이의 데이터만 저장할 수 있다.

- 한번 생성된 배열은 길이를 늘리거나 줄일 수 없다.

 

 

 


배열 선언) 

배열 선언의 형식은 2가지가 있다.

[]위치는 타입 선언 뒤에 붙을 수도 변수명 뒤에 붙을 수도 있다.

타입[] 변수; 타입 변수[];
int[] intArray;
double[] doubleArray;
String[] strArray;

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

 

배열 변수도 참조 변수에 속하고 배열은 객체이므로 힙 영역에 생성되고 배열 변수에 힙 영역 주소를 참조하게 된다. 배열 객체가 없다면 배열 변수는 null로 초기화 할 수 있다. 하지만 null상태에서 인덱스로 값을 읽거나 저장하려면, 참조하는 객체가 없기에 NullPointerException이 발생한다.

 

 


배열 생성) 

배열 객체를 생성하려면 값 목록을 이용하거나 new 연산자를 이용하는 방법이 있다.

 

* 값 목록으로 배열 생성

아래와 같은 형태로 배열 객체를 생성할 수 있다.

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

중괄호는 주어진 값을 항목으로 가지는 배열 객체를 힙 영역에 생성하고 배열 객체 번지를 return하고 이 번지값이 변수에 저장됨으로써 참조가 이루어 진다.

 

특정 인덱스의 값을 변경하고 싶다면 = 대입 연산자를 이용하면 된다.

names[1] = "홍길동";

 

배열 객체를 생성할 때 주의해야할 것이 있는데 배열 변수를 이미 선언한 후에는 다른 실행문에서 중괄호를 이용한 배열 생성이 허용되지 않는다.

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

변수 = new 타입[] { 값0, 값1, 값2, 값3 ..... }
String[] names = null;
names = new String[] {"홍길동", "이순신", "강감찬"}

 

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

매개 변수로 int[] 배열이 선언된 메소드가 있는 경우에도 값 목록으로 배열을 생성함과 동시에 add()의 매개값으로 사용하고자 하면 반드시 new 연산자를 사용해야한다.***

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);

//  int sum2 = add( {95, 85, 90} ); // 컴파일 에러
    int sum2 = add( new int[] {83, 90, 87});
    System.out.println("총합: "+sum2);
}

public static int add(int[] scores){
    int sum = 0;
    for(int i=0; i<3; i++){
        sum += scores[i];
    }
    return sum;
}

 

* new 연산자로 배열 생성

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

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

길이는 배열이 저장할 수 있는 값의 개수. 이미 배열 변수가 선언된 경우에도 new 연산자로 배열을 생성할 수 있다.

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

초기값은 타입마다 다르다.

참조타입 경우는 null이며 기본타입 경우 boolean은 false, char타입은 '\u0000',

byte, short, int 경우는 0, float는 0.0F, double은 0.0, long은 0L 이다. 

String[] arr1 = new String[3];
for(int i=0; i<3; i++){
    System.out.println("arr1["+i+"]: "+arr1[i]);
}
arr1[0] = "1월";
arr1[1] = "2월";
arr1[2] = "3월";
for(int i=0; i<3; i++){
    System.out.println("arr1["+i+"]: "+arr1[i]);
}
// arr1[0]: null
// arr1[1]: null
// arr1[2]: null
// arr1[0]: 1월
// arr1[1]: 2월
// arr1[2]: 3월

 

 


배열 길이) 

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

필드는 객체 내부의 데이터를 의미하는데 배열의 길이를 얻어려면 다음과 같은 배열 객체의 length 필드를 읽는다

배열변수.length;
int[] intArray = { 10, 20, 30 };
int num = intArray.length;	// 3

length 필드는 읽기 전용 필드이기 때문에 값을 바꿀수 없다. 배열 length는 보통 for문에서 사용해서 배열 전체를 루핑할 때 유용하게 사용한다.

String[] arr1 = { "1월", "2월", "3월" };
for(int i=0; i<arr1.length; i++){
    System.out.println("arr1["+i+"]: "+arr1[i]);
}
// arr1[0]: 1월
// arr1[1]: 2월
// arr1[2]: 3월

 

 


명령 라인 입력) 

프로그램 실행을 위해 main() 메소드가 필요하다는 것을 안다. 하지만 main() 메소드의 매개값인 String[] args가 왜 필요한걸까 

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

명령 라인(명령 프롬프트)에서 위 코드를 java 명령으로 실행하면 jvm은 길이가 0인 String 배열 args를 먼저 생성하고 man() 메소드를 호출할 때 매개값으로 전달한다. 

main() 메소드는 String[] args 매개 변수를 통해서 명령 라인에서 입력된 데이터의 수(배열의 길이)와 입력된 데이터(배열의 항목 값)을 알 수 있게 된다.

public class chap01 {
    public static void main(String[] args) {

        if(args.length != 2){
            System.out.println("값의 수가 부족합니다");
            System.exit(0);
        }

        String strNum1 = args[0];
        String strNum2 = args[1];

        int num1 = Integer.parseInt(strNum1);
        int num2 = Integer.parseInt(strNum2);

        System.out.println(num1 + num2);

    }
}

명령 프롬프트에서 컴파일하고 실행에 값을 넣어 출력한 결과

 

 

--- 다차원 배열부터 다음 포스팅에서 

 

 

 

04-1 / 조건문: if문, switch문

  • 조건문은 조건식에 따라 다른 실행문을 실행하기 위해 사용된다. 종류는 if문과 switch문 2가지가 있다.

if문) 

if문은 조건식의 결과가 true, false이냐에 따라 실행문이 결정된다.

따라서 조건식으로는 true, false 값을 낼 수 있는 연산식이나 boolean 타입의 변수가 올수 있다.

 

조건식이 true면 블록({내용})을 실행하고 그렇지 않다면 실행하지 않고 넘어간다.

if (조건식){
	실행문A
}
실행문B

조건식이 true 경우 : 실행문 A → 실행문 B
조건식이 false 경우 : 실행문 B

 

 

 

if-else문) 

if문은 조건식의 결과에 따라 실행 블록을 선택할 수 있게 하는 if-else문이 있다.

if (조건식){
	실행문A
} else {
	실행문B	
}
실행문C

조건식이 true 경우 : 실행문 A → 실행문 C
조건식이 false 경우 : 조건식 false → 실행문 B → 실행문C

 

 

 

if-else if-else문) 

조건문이 여러개인 if문도 있다.

if블록과 else블록 사이에 else if 블록을 넣음으로써 여러조건식 중 true인 블록만 실행하고 if문을 벗어나는 조건문이다.

if (조건식1){
	실행문A
} else if (조건식2){
	실행문B	
} else if (조건식3){
	실행문C
} else {
	실행문D
}
실행문E

(앞에 조건식을 거쳐 false가 되면 그다음 조건식으로 넘어가는 방식)

조건식1이 true 경우 :                                                     실행문 A → 실행문 E

조건식1이 false 이면서    조건식2가 true 경우 :    조건식1 false → 실행문 B → 실행문E
조건식1,2가 false 이면서 조건식3이 true 경우 :    조건식1 false 조건식2 false 실행문 C → 실행문E

조건식1,2,3 모두 false인 경우:                                      조건식1 false 조건식2 false 조건식3 false 실행문 D → 실행문E

 

 

if문을 이용하여 무작위 숫자에 대한 조건문 만들어보기) 

 

1. 임의의 정수를 뽑는 함수 Math.random() 을 사용

double randomNo = Math.random();
System.out.println(randomNo);

// 0.9533989939956973
// 0.4139816992085926
// 0.26388711048064784
// 매번 값이 다르다
0.0 <= Math.random() < 1.0

이 함수는 0.0 에서 1.0사이의 double타입의 난수(=랜덤한 수)를 리턴한다. (다만 0.0은 포함되나 1.0은 포함되지 않는다)

 

자신이 원하는 숫자와 자리수에 맞춰 수를 곱하고 캐스팅 연사자 (int)로 형 변환을 시키면 원하는 정수값을 얻을 수 있다.

0이상 60 미만 사이 정수값을 얻고싶으면 60을 곱하여 적용하면 되고

0.0 * 60 <= Math.random() * 60 < 1.0 * 60

1이상 60 이하 사이의 값을 얻고 싶다면 이에 +1를 적용하면 된다.

0.0 * 60 +1 <= Math.random() * 60 +1 < 1.0 * 60 +1
int randomNo = (int)(Math.random() * 60 + 1);

 

이를 이용한 if문 작성

int diceNo = (int)(Math.random() * 6 + 1);

if (diceNo == 1){
    System.out.println("1번");
} else if (diceNo == 2) {
    System.out.println("2번");
} else if (diceNo == 3) {
    System.out.println("3번");
} else if (diceNo == 4) {
    System.out.println("4번");
} else if (diceNo == 5) {
    System.out.println("5번");
} else {
    System.out.println("6번");
}

 

 

switch문) 

switch문은 변수의 값에 따라 실행문이 결정된다.

if문이 경우의 수가 true, false 두가지 뿐이기 때문에 경우의 수가 많아지면 else if가 많아지며 코드가 복잡해진다.

이때 switch문을 사용하면 간결해진다.

int diceNo = (int)(Math.random() * 6 + 1);

switch (diceNo){
    case 1:
        System.out.println("1번");
        break;
    case 2:
        System.out.println("2번");
        break;
    case 3:
        System.out.println("3번");
        break;
    case 4:
        System.out.println("4번");
        break;
    case 5:
        System.out.println("5번");
        break;
    default:
        System.out.println("6번");
}

중간에 break; 를 쓰는건 해당 case만 실행하고 switch문을 빠져나가기 위해서이다. 

break;가 없다면 그 다음 case들도 실행이 되며 다시 break;를 만나거나 switch문이 끝나기 전까지는 종료되지 않는다.

반대로 이를 이용해 두가지 케이스가 같은 실행문을 실행하게도 만들 수 있다.

char grade = 'B';

switch (grade){
    case 'A':
        System.out.println("A");
        break;
    case 'B':
    case 'b':
        System.out.println("B");
        break;
    case 'C':
        System.out.println("C");
        break;
    default:
        System.out.println("D");
}

// 대문자 B라 case B에 들어갔지만 break;가 없어 case b로 넘어가 실행하게 되어 
// 대문자 소문자 상관없이 동일한 처리를 하는 모습

 

 

 

 

 


04-2 / 반복문: for문, while문, do-while문

  • 반복문은 어떤 작업(코드)를 반복적으로 실행되도록 할 때 사용되며 종류에는 for문, while문, do-while문이 있다.

for문) 

for문과 while은 서로 변환이 가능하여 둘 중 어느거나 선택해서 사용하면 좋지만

for문은 보통 반복 횟수를 알고 있는 때 주로 사용한다.

 

반복문을 사용하지 않고 변수에 1부터 100까지 하나씩 더한다면 100줄의 실행문이 필요할 것이다.

int sum = 0;
sum = sum + 1;
sum = sum + 2; 
sum = sum + 3;
...
sum = sum + 100;

 그러나 for문을 사용한다면 단 몇줄로 줄일 수 있다.

int sum = 0;
for (int i=0; i<=100; i++){
    sum += i;
}

코드가 간결해지면 개발시간을 줄일 수 있고, 에러가 날 확률도 줄어든다.

 

for문 실행 흐름은

for ( int i = 0 ; i <= 100 ;  i++ ) { ④ 실행문 }
① 초기화식 ② 조건식 ③ 증감식

1. ①초기화식에 들어가서 실행

2. ②조건식을 평가한다

     true면 블록내부의 ④실행문을 실행  (false면 블록을 실행하지 않고 for문 종료)

3. ④실행문이 다 실행 되면 ③증감식을 실행하고 다시 2번 과정으로 돌아간다.

 

 

초기화식, 조건식, 증감식은 무조건 1개씩 있어야하는 건 아니다

초기화식이 없는 경우도 있고

int i = 1;
for (; i<=100; i++) { ... }

초기화식, 조건식, 증감식이 둘 이상인 경우도 있다. (이런경우는 ,로 구분)

for(int i=0, int j=100; i<=50 && j>=50; i++, j--) {...}

 

* for문에서 주의할 점은

- 초기화식에 선언된 변수는 로컬 변수로 for문을 나가서 사용할 수는 없다.

- 초기화식에서 루프카운터 변수로 float 타입을 사용하지 말야한다. (0.1f 가 우리가 생각하는 실제값보다 살짝 크다 부정확)

 

* 중첩 for문

for문 안에는 또다른 for문을 내포할 수 있는데 이를 중첩 for문이라 한다. 

바깥 for문이 한번 돌때 안쪽 for문은 정해진 횟수대로 도는 방식으로 돌아간다.

//구구단 
for(int m=2; m<=9; m++){
    System.out.println("*** "+m+"단 ***");
    for(int n=1; n<=9; n++){
        System.out.println(m +" x "+n+" = "+ (m*n));
    }
}
// 바깥 for문이 한번 돌때 안쪽 for문은 9번 돈다

 

 

 

while문) 

while문은 조건에 따라 반복할 때 주로 사용한다. 

int sum = 0;
int i = 1;
while (i<=100){
	sum += i
}

 

while문의 실행 흐름은 

for ( i<10 ) { ② 실행문 }
① 조건식 (참이면 계속 반복)

1. ①조건식을 평가한다

    true면 ②실행문을 실행한다. (false면 while문 종료)

2.  ②실행문이 모두 실행되면 다시 1번으로 돌아간다. 

 

* while문 주의 할 점

- 내부에서 계속 누적되는 값을 갖는 루프 카운터 변수는 while문 시작 전에 미리 선언해야한다.

- 조건식에 항상 참인 값이나 연산식이 있으면 while문은 무한히 돌게 된다. 이때, while문을 종료시킬 수 있는 장치를 만들어야 하는 데 변수값을 false로 변환시키거나 break문을 사용해야한다.

 

 

do-while문) 

while문과 거의 동일하지만 단 한가지 다른점이 있다.

do-while문의 경우에는 실행문을 최초에 한번 무조건 돌리고 나서 조건식에 따라 실행문을 반복할지 여부를 따지게 된다.

 

do-while의 실행 흐름은

do { sum+=(i+1); i++; } while ( i<10 );
① 실행문 ② 조건식

1. 처음 실행시 ①실행문 우선 실행

2. ②조건식을 평가한다

3. true면 ①실행문을 실행한다 (false면 do-while문을 종료)

4. ①실행문이 모두 실행되면 2번 과정으로 돌아간다.

 

 

break문) 

break문은 반복문인 for문, while문, do-while문의 실행을 중지하는 역할은 한다. 또한 조건문인 switch문도 종료시킨다.

break문은 대개 if문과 같이 사용되어 특정 조건에 따라 for문과 while문을 종료할 때 많이 사용한다.

while(true){
    int num = (int) (Math.random() *6 +1);
    System.out.println(num);
    if (num==6){
        break;
    }
}
// while구문은 조건식 자체가 true라 무한히 돌 예정이지만 숫자 6이 나온다면 무한 루프를 탈출하게 된다.

 

반복문이 중첩되어 있을 경우 안쪽 반복문에서 break를 선언하면 안쪽 반복문만 종료되고

바깥 반복문은 종료되지 않는다.

바깥 반복문까지 종료하려면 바깥 반복문에 이름(라벨)을 붙여주고 break뒤에 바깥 반복문 이름을 붙여 사용하면

바깥 반복문까지 함께 종료된다.

Outter: for(char upper='A'; upper<='Z'; upper++){
    for(char lower='a'; lower<='z'; lower++){
        System.out.println(upper +"-"+ lower);
        if(lower=='g'){
            break Outter;
        }
    }
}
System.out.println("프로그램 종료");

 

 

continue문) 

continue문은 반복문에서만 사용되는데 블록내부에서 continue문이 실행되면

for문의 조건식, while문, do-while문의 조건식 으로 이동한다. 

continue문은 break문과 달리 종료하지 않고 계속 반복하나 특정 조건에서만 반복을 피하고 싶을 때 많이 사용한다.

for(int i=1; i<=10; i++){
    if(i%2==0){
        continue;
    }
    System.out.println(i);
}
// 1부터 10사이의 홀수 숫자만 출력

 

 

 

Chapter 4 확인문제 

2번)

for문을 이용해 1부터 100까지 정수 중 3의 배수의 총합을 구하는 코드를 작성하세요

더보기
int sum = 0;
for(int i=1; i<=100; i++){
    if(i%3==0){
        sum += i;
    }
}
System.out.println(sum);
// 1683

 

3번)

while문과 Math.random()메소드를 이용해 2개의 주사위를 던졌을 때 나오는 눈을 (눈1, 눈2) 형태로 출력하고,

눈의 하비 5가 아니면 계속 주사위를 던지고, 눈 합이 5이면 종료하는 코드를 작성하세요

더보기
while(true){
    int diceNo1 = (int)(Math.random() *6 +1);
    int diceNo2 = (int)(Math.random() *6 +1);

    System.out.println("("+diceNo1+","+diceNo2+")");

    if(diceNo1+diceNo2 == 5){
        break;
    }
}

 

4번)

중첩 for문을 이용하여 방적식 4x+5y=60의 모든 해를 구해서 (x,y)형태로 출력해보세요. 

단, x와 y는 10이하의 자연수입니다.

더보기
for(int x =1; x<=10; x++){
    for(int y=1; y<=10; y++){
        if((4*x)+(5*y)==60){
            System.out.println("("+x+","+y+")");
        }
    }
}

 

5번)

for문을 이용해서 다음과 같이 *을 출력하는 코드를 작성해보세요

*
**
***
****
더보기
for(int x =1; x<=4; x++){
	System.out.println("*".repeat(x));
}

 

6번)

for문을 이용해서 다음과 같이 *을 출력하는 코드를 작성해보세요

   *
  **
 ***
****
더보기
for(int x =1; x<=4; x++){
	System.out.println(" ".repeat(4-x)+"*".repeat(x));
}

 

7번)

while문과 Scanner을 이용해서 키보드로 입력된 데이터로 예금, 출금, 조회, 종료 기능을 제공하는 코드를 빈공간에 작성해보세요. 프로그램을 실행하면 다음과 같은 실행결과가 나와야합니다(Scanner의 nextLine()사용) ***

boolean run = true;
int balance = 0;
Scanner scanner = new Scanner(System.in);

while(run) {
    System.out.println("-----------------------------------");
    System.out.println("1.예금 | 2.출금 | 3.잔고 | 4.종료");
    System.out.println("-----------------------------------");
    System.out.println("선택 > ");

    빈공간

}

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

//-----------------------------------
//1.예금 | 2.출금 | 3.잔고 | 4.종료
//-----------------------------------
//선택 > 1
//예금액>10000
//-----------------------------------
//1.예금 | 2.출금 | 3.잔고 | 4.종료
//-----------------------------------
//선택 > 2
//출금액>2000
//-----------------------------------
//1.예금 | 2.출금 | 3.잔고 | 4.종료
//-----------------------------------
//선택 > 3
//잔고>8000
//-----------------------------------
//1.예금 | 2.출금 | 3.잔고 | 4.종료
//-----------------------------------
//선택 > 4
//프로그램 종료
더보기
boolean run = true;
int balance = 0;
Scanner scanner = new Scanner(System.in);

while(run) {
    System.out.println("-----------------------------------");
    System.out.println("1.예금 | 2.출금 | 3.잔고 | 4.종료");
    System.out.println("-----------------------------------");
    System.out.println("선택 > ");

    String num = scanner.nextLine();
    String moneyString;
    int money = 0;

    switch(num){
        case "1":
            System.out.println("예금액>");
            moneyString = scanner.nextLine();
            money = Integer.parseInt(moneyString);
            balance += money;
            break;
        case "2":
            System.out.println("출금액>");
            moneyString = scanner.nextLine();
            money = Integer.parseInt(moneyString);
            balance -= money;
            break;
        case "3":
            System.out.println("잔고>" +balance);
            break;
        case "4":
            run = false;
            break;
    }
}
System.out.println("프로그램 종료");

 

 

+ Recent posts