본문 바로가기
개발자 꿈나무의 하루/01_Boot Camp

(네이버클라우드 부트캠프) 12일차 - Java프로그래밍 기초(표준입출력,String), 실습프로젝트(메서드)

by kk_naks 2024. 6. 11.

1. 메서드의 종류

  1.1 메서드

- 메서드 : 클래스 내부의 기능을 구현(함수를 실행하는 것)이다.
- 메서드는 클래스메서드와 인스턴스메서드가 있다.

  1.2 클래스 메서드

- 객체에 종속되지 않는 기능을 제공한다. 
- 객체의 상태에 영향을 받지 않는 독립적인 작업을 수행한다.
- 클래스 메서드는 객체의 생성 없이 직접 호출할 수 있다.

  1.3 인스턴스 메서드

- 특정 객체에 종속된 기능을 제공한다.
- 객체의 상태를 변경하거나 해당 객체의 속성을 조작하는 작업을 수행한다.
- 인스턴스를 생성한 후에만 호출할 수 있다.

- 객체에 종속되기 때문에 인스턴스를 생성하여 레퍼런스를 사용해야한다. 

2. 표준입출력

  2.1 표준입출력의 시스템정보

- 표준입출력은 인스턴스 메서드로 객체에 종속되어 있다. 
- 기본적으로 프로그램이 제공하는 표준입출력은 다음과 같다.

 

- 이는 시스템상에서도 간단히 확인 해 볼 수 있다.

키보드로 입력을 한 경우
파이프라인을 통해 stdout을 stdin으로 넘겨 받는경우

  2.2 표준입출력 스트림

- 표준입출력 스트림의 구조는 다음과 같다. 
입력스트림.read(); //return 값으로 1byte를 읽어온다.
//System.in   -> consol키보드 입력으로 부터 읽는다.
//파일입력스트림  -> 파일 입력으로 부터 읽는다.
//소켓입력스트림  -> 네트워크로 부터 읽는다.

출력스트림.println("Hello"); 
//System.out   -> consol창으로 출력 
//파일입력스트림  -> 파일로 출력
//소켓입력스트림  -> 네트워크로 출력

 

  2.3 Scanner

- java.util.Scanner로 인스턴스 메서드이다.

- 입력 스트림을 통해 받은 입력값을 Scanner인스턴스에 전달하여 next()메서드를 사용(call)하는 구조이다. 

  2.4 nextLine()

    -키보드 입력이 다음과 같이 입력되면 키보드 버퍼에는 다음과 같이 저장이 된다. 

//키보드 입력
aa bb 
cc
a b

//Scanner 코드
java.util.Scanner keyboardScan = new Scanner(System.in);

String s1 = keyboardScan.nextLine();
String s2 = keyboardScan.nextLine();
String s3 = keyboardScan.nextLine();

 

키보드 버퍼

- nextLine()은 입력 버퍼에서 LF(Line Feed)까지 스캔한다.
- 이후 LF(\n)를 제거하고 String 객체에 할당한다. 

 

  2.5 next(),nextInt()....

- next()류의 Scanner는 공백을 기준으로 공백 전까지 Scan을 한다.
- 시작점에 공백부터(있을시) ~ 다음 공백직전까지
- Scanner보다 입력버퍼에 데이터가 남아있으면 해당 버퍼를 읽게 된다.
- Scan종료시, nextLine()을 통해 초기화가 필요하다.

3. String

  3.1 String 레퍼런스

- String은 primitive data type이 아니다.
- primitive data type : byte,int,short,long,float,double,boolean,char
- String은 배열과 마찬가지로 레퍼런스(인스턴스의 주소를 담는 변수)이다.

 

 

  3.2 String const pool

- new로 통해 객체를 생성하면 Heap영역에 생성
- 상수스트림(" ")을 통해 생성하면 String const pool에 String이 생성
package study.lang.string;

public class Test03 {
  public static void main(String[] args) {
    String s1 = new String("Hello");
    String s2 = new String("Hello");
    String s3 = "Hello";
    String s4 = "Hello";
    String[] s5 = new String[] {"Hello", "World"};

    // identityHashCode를 사용하여 객체의 해시 코드 출력
    System.out.printf("%x\n", System.identityHashCode(s1));
    System.out.printf("%x\n", System.identityHashCode(s2));
    System.out.printf("%x\n", System.identityHashCode(s3));
    System.out.printf("%x\n", System.identityHashCode(s4));
    System.out.printf("%x\n", System.identityHashCode(s5));
    System.out.printf("%x\n", System.identityHashCode(s5[0]));
    System.out.printf("%x\n", System.identityHashCode(s5[1]));
  }
}

 

 

- 출력 결과 
- s3, s4, s5[0]은 모두 같은 레퍼런스를 갖는다. 
- 즉, String const pool을 통해 동일한 문자열에 대한 생성을 제한하고 하나의 레퍼런스를 사용한다.

 

4. 실습프로젝트 메서드

  4.1 Scanner.nextLine()

//기존코드 
int menuNo;
while (true) {
    try {
        System.out.print("> ");
        menuNo = keyboardScanner.nextInt();

        if (menuNo >= 1 && menuNo <= menus.length) {
            if (menus[menuNo - 1] == "종료") {
                break;
            }
            System.out.println(menus[menuNo - 1]);
        } else {
            System.out.println("유효한 메뉴 번호가 아닙니다.");
        }
    } catch (InputMismatchException ex) {
        System.out.println("숫자로 메뉴 번호를 입력하세요.");
        keyboardScanner.next();
    }
}

System.out.println("종료합니다.");
- 기존코드에서 nextLine()으로 수정
- 입력버퍼의 나머지 값이 없음.
- menu를 입력 받을 때 동작추가 
String command;
while (true){
    System.out.print("> ");
    command = keyboard.nextLine();
    try{
        if (command.equals("menu")){
            System.out.println("메뉴실행");
        }else{
           int menuNo = Integer.parseInt(command);
            if (menuNo >= 1 && menuNo <= menus.length){
                if (menus[menuNo - 1].equals("종료")){
                    break;
                }
                System.out.printf("%d. %s\n",menuNo, menus[menuNo -1]);
            } else {
                System.out.println("유효한 메뉴 번호가 아닙니다.");
            }
        }
    } catch(NumberFormatException ex){
        System.out.println("숫자로 메뉴 번호를 입력하세요.");
    }
}

 

  4.2 메서드 생성

- 메서드의 장점
- 중복 코드를 분리하여 유지보수 용이하다.
- 기능 단위로 명령어로 묶어 코드의 가독성을 향상시킨다.
- 코드의 재사용률이 올라가여 다른 프로젝트에도 적용하기 용이하다. 

 

    -요구사항

- 1) 메뉴를 출력하는 코드를 printMenu() 메서드로 묶어 사용한다.
- 2) 사용자로부터 명령을 입력 받는 코드를 prompt() 메서드로 묶어 사용한다.
- 3) 메뉴 번호의 유효성을 검증하는 코드를 isValidateMenu() 메서드로 묶어 사용한다.
- 4) 메뉴 타이틀을 알아내는 코드를 getMenuTitle() 메서드로 묶어 사용한다.
- 5) 메뉴를 처리하는 조건문(유효한 번호, 유효하지 않은 번호, 종료)을 정리한다.
//printMenu()
static void printMenu(){
    String boldAnsi = "\033[1m";
    String redAnsi = "\033[31m";
    String resetAnsi = "\033[0m";

    String appTitle = "[팀 프로젝트 관리 시스템]";
    String line = "----------------------------------";

    System.out.println(boldAnsi + line + resetAnsi);
    System.out.println(boldAnsi + appTitle + resetAnsi);

    for (int i = 0; i < menus.length; i++) {
        if (menus[i].equals("종료")) {
            System.out.printf("%s%d. %s%s\n", (boldAnsi + redAnsi), (i + 1), menus[i], resetAnsi);
        } else {
            System.out.printf("%d. %s\n", (i + 1), menus[i]);
        }
    }

    System.out.println(boldAnsi + line + resetAnsi);
}
//prompt()
static String propmpt(){
	System.out.print("> :");
    return keyboard.nextLine();
}

//isValidateMenu()
static boolean isValidateMenu(int menuNo){
	return (menuNo >= 1 && menuNo<=6);
}

//getMenuTitle()
static String getMenuTitle(int menuNo){
	return isValidateMenu(menuNo)? menus[menuNo-1] : null; 
}

 

if(조건){ 문장;
} else {문장
           if(조건){
                       if(조건)
           } else {}
}
구조 단순화 하기
String command;
while (true) {
    try {
        command = prompt();
        if (command.equals("menu")) {
            printMenu();
        } else {
            int menuNo = Integer.parseInt(command);
            String menuTitle = getMenuTitle(menuNo);
            if (isValidateMenu(menuNo) {
                if (menuTile.equals("종료")) {
                    break;
                }
                System.out.println(menuTile);
            } else {
                System.out.println("유효한 메뉴 번호가 아닙니다.");
            }
        }
    } catch (NumberFormatException ex) {
        System.out.println("숫자로 메뉴 번호를 입력하세요.");
    }
}

 

String command;
while (true) {
    try {
        command = prompt();
        if (command.equals("menu")) {
            printMenu();
        } else {
            int menuNo = Integer.parseInt(command);
            String menuTitle = getMenuTitle(menuNo);
            if (menuTitle == null){
            	System.out.println("유효한 메뉴 번호가 아닙니다.");
            } else if (menuTitle.equals("종료")){
            	break;
            } else{
            	System.out.println(menuTile);
            }
        }
    } catch (NumberFormatException ex) {
        System.out.println("숫자로 메뉴 번호를 입력하세요.");
    }
}

 

  4.3 완성된 코드

package bitcamp.myapp2;
import java.util.Scanner;

public class App {
    static String[] menus = new String[]{
            "회원",
            "팀",
            "프로젝트",
            "게시판",
            "도움말",
            "종료",
    };
    static Scanner keyboard = new Scanner(System.in);

    public static void main(String[] args) {
        printMenu();
        String command;
        while (true){
            command = prompt();
            try{
                if (command.equals("menu")){
                    printMenu();
                }else{
                   int menuNo = Integer.parseInt(command);
                   String menuTitle = getMenuTitle(menuNo);
                   if (menuTitle == null){
                       System.out.println("유효한 메뉴 번호가 아닙니다.");
                   } else if (menuTitle.equals("종료")){
                       break;
                   } else {
                       System.out.printf("%d. %s\n",menuNo, menuTitle);
                   }
                }
            } catch(NumberFormatException ex){
                System.out.println("숫자로 메뉴 번호를 입력하세요.");
            }
        }
        System.out.println("종료합니다");
        keyboard.close();
    }
    static void printMenu(){
        //글자색,굵기 설정
        String redAnsi = "\033[31m";
        String boldAnsi = "\033[1m";
        String resetAnsi = "\033[0m";

        //메뉴초기 설정
        String appTitle = "[팀프로젝트 관리 시스템]";
        String line = "---------------------------";


        //메뉴화면 출력
        System.out.printf("%s%s%s\n",boldAnsi,line,resetAnsi);
        System.out.printf("%s%s%s\n",boldAnsi,appTitle,resetAnsi);
        for (String menu : menus){
            if (menu.equals("종료")) {
                System.out.printf("%s%s%s\n",(boldAnsi+redAnsi),menu,resetAnsi);
            }else {
                System.out.printf("%s\n",menu);
            }
        }
        System.out.printf("%s%s%s\n",boldAnsi,line,resetAnsi);
    }
    static String prompt(){
        System.out.print("> ");
        return keyboard.nextLine();
    }
    static boolean isValidateMenu(int menuNo){
        return (menuNo >= 1 && menuNo <= menus.length);
    }
    static String getMenuTitle(int menuNo){
        return isValidateMenu(menuNo)? menus[menuNo-1] : null;
    }
}