23일차_예외처리, String 클래스, 로그인 액션
------------------------------------------
예외처리
1. 프로그램 실행은 다음과 같은 절차에 의해 진행된다.
소스코드 작성 및 .java 파일 생성->컴파일->.class 파일 생성->실행
2. 소스코드 작성시 올바른 문법과 키워드를 사용했는지에 대한 검사는 컴파일 과정에서 검사되고, 오류가 있는 경우 컴파일이 완료되지 않는다.->컴파일 오류
3. 컴파일 과정이 정상적으로 진행되고 .class 파일이 생성되면 실행할 수 있다. 이때 실행시 논리적인 오류로 인해 실행이 안되는 경우가 있다->실행 오류
4. 실행 오류에는 비정상적인 종료를 막을 수 없는 오류(error)와 비정상적인 종료를 막을 수 있는 예외(exception)로 구분된다.
예외의 예는, 탐색기 프로그램을 실행하는 과정에서 CD를 필요로 하는 CD 드라이브 접근시 CD를 넣지 않은 상태에서 접근을 시도하면 'CD를 필요로 합니다'라는 메시지를 보여주고 접근 시도를 종료하는 것이다. 탐색기 프로그램의 비정상적인 종료는 되지 않는다.
5. 예외처리는 비정상적인 종료를 막을 수 있는 경우를 사전에 확인해서 처리하는 방법이다.
6. 예외처리 기본형식
try {
//예외가 발생할 수 있는 구문
} catch (예외형식) {
//예외 처리 구문
}
try {
//예외가 발생할 수 있는 구문
} catch (하위예외형식) {
//예외 처리 구문
} catch (상위예외형식) {
//예외 처리 구문
} catch (최상위예외형식) {
//예외 처리 구문
}
try {
//예외가 발생할 수 있는 구문
} catch (예외형식) {
//예외 처리 구문
} finally {
//예외 발생과 관계없이 항상 실행해야 하는 구문
}
//Sample101.java
package com.test;
import java.util.*;
public class Sample101 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
do {
System.out.print("양의 정수(a, -1 exit)?");
int a = sc.nextInt();
if (a == -1) {
break;
}
System.out.print("양의 정수(b)?");
int b = sc.nextInt();
/*
//(정수1/정수2) 에서 정수2가 0이면 예외 발생
//-> 비정상적인 종료
System.out.printf("%d / %d = %d %n%n"
, a, b, (a/b));
*/
//예외처리
//->비정상적인 종료를 막는다.
try {
//(정수1/정수2) 에서 정수2가 0이면 예외 발생
System.out.printf("%d / %d = %d %n%n"
, a, b, (a/b));
} catch(Exception e) {
System.out.printf("0으로 나눌 수 없습니다.%n%n");
//System.out.println(e.getMessage());
//System.out.println(e.toString());
}
}while(true);
sc.close();
}
}
6. 메소드 내부에서 직접 예외를 처리하는 것이 아니라 자기를 호출한 위치에서 예외를 처리하도록 예외를 밖으로 보낼 수 있다. throws 구문이 있는 메소드를 호출하는 곳에서는 반드시 예외를 처리해야 한다. 단, 자기 자신도 또다른 메소드인 경우는 throws 를 이용해서 예외를 밖으로 보낼 수 있다. 마지막 실행 메소드인 main() 메소드에서도 throws로 예외를 처리하는 경우는 JVM이 예외를 처리하게 된다.
-> throws 예외형식
접근지정자 반환자료형 메소드이름(매개변수) throws 예외형식 {
//예외가 발생할 수 있는 구문
}
//Sample102.java
package com.test;
import java.util.*;
public class Sample102 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("정수(a)?");
//정수 입력 받는 과정이지만 자료형을 String으로 처리.
String a = sc.next();
System.out.print("정수(b)?");
String b = sc.next();
//java.lang.NumberFormatException 예외 발생 가능 -> 비정상적인 종료 가능
int ia = Integer.parseInt(a); //String->int
int ib = Integer.parseInt(b); //String->int
//java.util.IllegalFormatConversionException 발생 가능 -> 비정상적인 종료 가능
System.out.printf("%s + %s = %d %n"
, a, b, (ia + ib));
sc.close();
}
}
7. 사용자가 예외를 발생시키려면 throw new 예외객체("메시지"); 구문을 사용한다.
//ExceptionTest.java
package com.test;
public class ExceptionTest {
//산술식 분석 및 결과 반환 전용 메소드
public static int operator(String a, String op, String b) throws Exception {
int result = 0;
if (op.equals("+")
|| op.equals("-")
|| op.equals("*")) {
//정상 실행
//+, -, * 연산 액션 추가
} else {
//예외 발생
//-> return 구문에 관계없이 메소드 실행 중지
//-> throw 구문 사용
//-> throws 구문 추가
throw new Exception("연산자 +, -, * 만 가능.");
}
return result;
}
}
//Sample103.java
package com.test;
import java.util.*;
public class Sample103 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//외부에서 입력된 산술식 분석 및 결과 출력
// a + b 또는 a - b, a * b
// 산술식에서 산술연산자는 +, -, * 만 인정
// 그 외에는 예외 발생.
System.out.print("산술식(a 연산자 b)?");
String a = sc.next();
String op = sc.next();
String b = sc.next();
try {
//산술식 분석 및 결과 반환 전용 메소드 호출
//->예외 발생 가능
//->예외 처리 구문 추가
int result = ExceptionTest.operator(a, op, b);
System.out.printf("%s %s %s = %d %n"
, a, op, b, result);
} catch(Exception e){
System.out.println(e.toString());
}
sc.close();
}
}
-----------------------------------------
요약
1. 프로그램에서 발생하는 예외(Exception)를 사용자가 처리함으로써 비정상적 종료를 막을 수 있다.
2. try ~ catch, try ~ catch ~ catch ..., try ~ catch ~ finally 구문 사용.
3. try 블럭에는 예외 발생 가능한 구문, catch는 예외를 처리하는 예외형식 및 예외 처리 구문 지정.
4. 예외 발생 가능한 구문을 포함하고 있는 메소드에서 예외를 자체적으로 처리하지 않고 밖으로 내보낼 수 있다.
-> throws 예외형식
5. 예외 상황을 만들어서 예외를 발생시킬 수 있다.
-> throw new 예외형식();
-----------------------------------------------
java.lang 패키지
String 클래스
- String 클래스에는 문자열을 저장하기 위해서 문자형 배열 변수릉 인스턴스 변수로 정의해놓고 있다.
- 한 번 생성된 문자열은 수정 불가능 상태가 된다(final 변수)
String a = "a";
String b = "b";
String a = a + b;
//"a", "b", "ab"가 독립적으로 존재하게 된다.
//더 이상 "a"는 참조주소를 저장하는 변수가 없기 때문에 가비지 컬렉터의 대상이 된다.
//-> StringBuffer, StringBuilder 클래스를 이용하게 되면 가비지가 발생하지 않는다. 문자열 객체를 내부적으로 수정할 수 있기 때문이다.
- String 클래스의 메소드
charAt()
concat()
contains()
endsWith()
equals()
equalsIgnoreCase()
indexOf()
lastIndexOf()
length()
replace()
replaceAll()
split()
startsWith()
substring()
toLowerCase()
toString()
toUpperCase()
trim()
valueOf()
//Main.java
package com.test;
public class Main {
public static void main(String[] args) {
String str1 = "TEST";
String str2 = new String("HELLO");
//문자열의 특정 번째 문자 반환
System.out.println(str1.charAt(0)); //char, 'T'
System.out.println(str1.charAt(1)); //char, 'E'
//문자열 결합
System.out.println(str1.concat(str2)); //"TESTHELLO"
System.out.println(str1 + str2); //"TESTHELLO"
//문자열 검색(포함)
System.out.println(str1.contains("LLO")); //false
System.out.println(str2.contains("LLO")); //true
//문자열 검색(시작, 끝 글자)
System.out.println(str1.startsWith("T")); //true
System.out.println(str1.endsWith("T")); //true
//문자열 비교(대소문자 구분 하는 경우)
System.out.println(str1.equals("test")); //false
//문자열 비교(대소문자 구분 없는 경우)
System.out.println(str1.equalsIgnoreCase("test")); //true
//문자열 대소문자 변환
System.out.println(str1.toLowerCase()); //"test"
System.out.println(str1.toUpperCase()); //"TEST"
//문자열 검색(위치)
System.out.println(str1.indexOf("TE")); //0
System.out.println(str1.indexOf("HE")); //-1
//D:\Berryz_WebShare\webshare.exe
//->D:\Berryz_WebShare
//->webshare.exe
String str3 = "D:\\Berryz_WebShare\\webshare.exe";
System.out.println(str3.indexOf("\\")); //2
System.out.println(str3.lastIndexOf("\\")); //18
//문자열 분리
System.out.println(str3.substring(str3.lastIndexOf("\\")+1)); //"webshare.exe"
System.out.println(str3.substring(0, str3.lastIndexOf("\\"))); //"D:\Berryz_WebShare"
//문자열 치환
System.out.println(str3.replace('_', '-')); //"D:\Berryz-WebShare\webshare.exe"
System.out.println(str3.replaceAll(".exe", ".zip")); //"D:\Berryz_WebShare\webshare.zip"
}
}
--------------------------------------
과제) 로그인 절차가 필요한 회원 관리
실행예)
--- 회원 관리 ---
1. 회원 가입 (ID, PW, NAME, TEL)
2. 회원 명단 출력(로그인 필요)
선택(1~2, 0 종료)?1
ID: XXXX
PW: 1111
NAME: SSSS
TEL: 010-123-3211
(저장소가 모자란 경우 자동으로 확장(+5)하는 액션 진행)
회원 가입이 완료되었습니다.
--- 회원 관리 ---
1. 회원 가입 (ID, PW, NAME, TEL)
2. 회원 명단 출력(로그인 필요)
선택(1~2, 0 종료)?2
ID PW? XXXX 2222
아이디 또는 패스워드가 틀렸습니다.
--- 회원 관리 ---
1. 회원 가입 (ID, PW, NAME, TEL)
2. 회원 명단 출력(로그인 필요)
선택(1~2, 0 종료)?2
ID PW? XXXX 1111
ID NAME TEL
------------------
....
총 4명
-----------------------------
//Member.java
package com.test;
//자료형 클래스
public class Member {
//멤버변수, getter, setter
//멤버변수 -> id, pw, name, tel -> String
}
//MenuAction.java
package com.test;
import java.util.*;
//메뉴별 액션 처리 클래스
public class MenuAction {
//저장소(배열) 준비
//1. 회원 가입 (ID, PW, NAME, TEL)
public void memberInsert(Scanner sc) {
//외부 데이터 입력 액션
//->id, pw, name, tel
//->저장소(배열)에 저장하는 액션
//->저장소가 모자란 경우 자동 확장 -> private 메소드
}
//2. 회원 명단 출력(로그인 필요)
public void memberList(Scanner sc) {
//외부 데이터 입력 액션
//->id, pw
//->id, pw 검사 과정 -> private 메소드
//회원 명단 출력 액션
//->인원수 출력 -> private 메소드
}
//private 메소드
}
//Main.java
package com.test;
import java.util.*;
//메인 메뉴 액션 클래스
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
MenuAction menu = new MenuAction();
do {
//메뉴 출력
//메뉴 입력
break;
//메뉴 선택
}while(true);
sc.close();
}
}
-----------------------------------------------------