기록
day 0528 StringAndStringBuffer_예외처리 본문
<< 문자열 처리 >>
String : 변하지않는(immutable) 문자열
StringBuffer(StringBuilder) : 변하는 문자열
package com.kosta.exam01;
/*
원래 String은 참조자료형 입니다 따라서 new String()처럼 사용해야 해요
그러나 문자열은 다른것들보다 훨씬 더 많이 사용하는 참조자료형이기 때문에
마치 기본자료형처럼 쓰는것을 허용해요
String data = new String("hello");
String data = "hello";
*/
public class StringTest {
public static void main(String[] args) {
// garbage 생성
String data = new String("hello");
System.out.println(data);
//새로운 객체 생성
data = data + " java";
System.out.println(data);
}
}
package com.kosta.exam01;
public class StringBufferTest {
public static void main(String[] args) {
StringBuffer data = new StringBuffer("hello");
System.out.println(data);
// 객체 자신이 바뀐다
data.append(" java");
System.out.println(data);
}
}
package com.kosta.exam01;
public class StringAndStringBuffer {
public static void pro(String data) {
System.out.println(data + "를 처리하였습니다.");
}
public static void main(String[] args) {
StringBuffer cmd = new StringBuffer();
cmd.append("insert ");
cmd.append("into ");
cmd.append("member ");
cmd.append("values() ");
cmd.append("name");
cmd.append(", '010'");
cmd.append("사과 ");
cmd.append("포도 ");
cmd.append("사과 ");
System.out.println(cmd);
// pro(cmd);
pro(cmd.toString());
}
}
위의 코드는 변하는 문자열 처리를 위하여
StringBuffer를 사용한 예를 보여주고 있다
그러나 대부분의 문자열을 매개변수로하는 메소드들은 String을 매개변수로 하도록 되어있으므로
StringBuffer를 String으로 변환한 후에 호출해야 합니다
<< 예외처리 >>
프로그램 실행중에 발생할 수 있는 예기치않는 상황에 대한 처리를 말한다
몇가지 예기치않은 상황에 대한 예를 들어보면
배열의 크기가 n이면 사용할 수 있는 인덱스는 0 ~ n-1 까지 입니다
그 범위가 아닌 인덱스에 접근하는 상황
또, 어떤 수를 0으로 나누는 상황
문장자체에 문법적 오류는 없으나 실행중에 사용자의 입력값이 바람직하지 않아
발생할 수 있는 예기치 않는 상황을 말합니다
/EditPlus/
// 프로그램 실행시에 두 개의 정수를 전달받아 나누기한 결과를 출력
class Calc {
public static void main(String[] args) {
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int div = a/b;
System.out.println("나누기결과 : " + div);
}
}
자바는 대부분 프로그램 실행 중에 발생할 수 있는 예기치않는 상황들에 대해 class로 만들어져있다
위의 프로그램은 문법적으로 오류가 없고 실행시에 만족하는 값을 전달하면
정상적으로 동작하는 프로그램입니다
그러나 만약 프로그램 실행시에 다음과 같이 두개의 정수를 전달하지 않거나
부적합한 값을 전달하게되면 프로그램 실행시에 예기치않는 상황 즉 "예외"가 발생합니다
자바에서는 대부분(일반적으로) 일어날 수 있는 "예외"에 대하여 이미 클래스로 만들어 두었습니다
그래서 그 상황이 되면 자동으로 예외 객체를 생성 해 줍니다
예를 들어 배열의 인덱스 범위를 넘으면 ArrayIndexOutOfBoundsException 객체가 자동으로 생성되고
숫자 형식에 맞지않으면 NumberFormatException 객체가 자동으로 생성됩니다
<< 예외 처리 방법 >>
1)
try {
예외가 발생 할 만한 문장(들)
}catch(예외클래스명 변수명){
예외가 발생되었을 때 처리 할 명령어(들)
}catch(){
}catch(){
하나의 try안에 catch가 여러개 올 수 있다
}
// 프로그램 실행시에 두 개의 정수를 전달받아 나누기한 결과를 출력
class Calc01 {
public static void main(String[] args) {
try{
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int div = a/b;
System.out.println("나누기결과 : " + div);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("나누기 할 두 수를 전달 해 주세요.");
}
}
}
// 프로그램 실행시에 두 개의 정수를 전달받아 나누기한 결과를 출력
class Calc02 {
public static void main(String[] args) {
try{
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int div = a/b;
System.out.println("나누기결과 : " + div);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("나누기 할 두 수를 전달 해 주세요.");
}catch(ArithmeticException e){
System.out.println("0으로 나눌 수 없어요.");
}catch(NumberFormatException e){
System.out.println("숫자로 전달 해 주세요.");
}
}
}
2)
class Calc03 {
public static void main(String[] args) {
try{
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int div = a/b;
System.out.println("나누기결과 : " + div);
}catch(Exception e){
System.out.println("나누기 할 두개의 정수를 전달 해 주세요.");
}
}
}
error: exception ArithmeticException has already been caught }catch(ArithmeticException e){
class Calc04 {
public static void main(String[] args) {
try{
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int div = a/b;
System.out.println("나누기결과 : " + div);
}catch(Exception e){
System.out.println("나누기 할 두개의 정수를 전달 해 주세요.");
}catch(ArithmeticException e){ // Exception e 부모클래스에서 처리되서 오지않는다
System.out.println("0으로 나눌 수 없어요.");
}
/*
error: exception ArithmeticException has already been caught
}catch(ArithmeticException e){
catch(Exception e) 이미 모든 예외상황을 처리하기 때문에
catch(ArithmeticException e) 으로 올 수가 없어요
이와 같이 catch절을 여러개 쓸 때에는 자식의 catch절이 먼저 와야 합니다
*/
}
}
/Exception e, ArithmeticException e 순서 바꾸기/
class Calc05 {
public static void main(String[] args) {
try{
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int div = a/b;
System.out.println("나누기결과 : " + div);
}catch(ArithmeticException e){
System.out.println("0으로 나눌 수 없어요.");
}catch(Exception e){
System.out.println("나누기 할 두개의 정수를 전달 해 주세요.");
}
}
}
class Calc06 {
public static void main(String[] args) {
try{
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int div = a/b;
System.out.println("나누기결과 : " + div);
System.out.println("작업종료");
}catch(ArithmeticException e){
System.out.println("0으로 나눌 수 없어요.");
}catch(Exception e){
System.out.println("나누기 할 두개의 정수를 전달 해 주세요.");
}
}
}
/*
만약 정상적으로 동작하는 경우에는
try안의 맨 마지막 문장을 동작하여 "작업종료"를 출력합니다
그러나 예외의 상황이되면 해당 catch절을 수행하고 try안의 다음 명령을 동작하지 않습니다
즉 예외의 상황이되면 "작업종료를 출력하지 않아요
*/
/finally/
class Calc07 {
public static void main(String[] args) {
try{
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int div = a/b;
System.out.println("나누기결과 : " + div);
}catch(ArithmeticException e){
System.out.println("0으로 나눌 수 없어요.");
}catch(Exception e){
System.out.println("나누기 할 두개의 정수를 전달 해 주세요.");
}finally{
// 반드시 수행해야 할 명령어
System.out.println("작업종료");
}
}
}
/*
finally
정상동작하거나 예외가 발생하거나 반드시 수행시키고자 하는 명령어를 써 줍니다
*/
/메소드 안에서 예외가 발생하는 경우/
1) 메소드 자신이 직접 try~catch로 처리한다
2) 메소드 호출하는 쪽으로 예외처리를 맡긴다 (throws)
class ExceptionTest01 {
// 메소드안에서 예외가 나는 경우
public static void calcDiv(int a, int b){
int r = a/b;
System.out.println("나누기 결과 : " + r);
}
public static void main(String[] args) {
calcDiv(4, 0);
}
}
/메소드 안에서 try~catch 처리하기/
class ExceptionTest02 {
// 메소드 자신이 직접 try~catch로 처리한다
public static void calcDiv(int a, int b){
try{
int r = a/b;
System.out.println("나누기 결과 : " + r);
}catch(Exception e){
System.out.println("나누기 할 두 수를 확인하세요.");
}
}
public static void main(String[] args) {
calcDiv(4, 0);
}
}
/throws 메소드 호출하기/
class ExceptionTest03 {
// throws 예외 종류 나열
public static void calcDiv(int a, int b) throws ArithmeticException {
int r = a/b;
System.out.println("나누기 결과 : " + r);
}
public static void main(String[] args) {
try{
calcDiv(4, 2);
calcDiv(4, 0);
}catch(ArithmeticException e){
// e, e.getMessage() : 예외에 대한 정보를 갖고있다
System.out.println("예외발생 : " + e.getMessage());
}
}
}
- 예외처리
: 프로그램 코드에는 문제가 없고 잘 컴파일이 되고 실행도 되지만
프로그램 실행중에 사용자의 부주의 등으로 인하여 발생할 수 있는 예기치않는 상황을 "예외"라고 하며
그것을 처리하는 것을 "예외처리"라고 합니다
- 메소드에서 예외처리하는 방법
1) 메소드 자신이 try~catch로 예외처리 한다
try{
예외가 발생할만한 명령어
}catch(예외클래스명 변수명)
예외가 발생되었을 때 처리할 명령어
}
2) 메소드 호출하는 쪽으로 예외처리를 전파한다
public 리턴타입 메소드명([매개변수]) throws 예외클래스명, 예외클래스명..{
}
하나의 try에 여러개의 catch가 올 수도 있어요
(단, catch절의 예외클래스가 상속관계에 있을 때 자식의 예외클래스가 먼저 오도록 해야합니다)
try{
}catch(예외클래스명 변수명){
}catch(예외클래스명 변수명){
}
- finally
: 예외가 발생하면 문제가 발생하는 것 이기 때문에
해당 catch절만 수행하고 try문의 그 이후의 명령은 동작하지 않아요
예외가 발생하거나 정상동작하거나 반드시 수행시키고자 하는 명령어(들)를 여기 써줍니다
try{
}catch(예외클래스명 변수명){
}catch(예외클래스명 변수명){
}finally{
}
- RuntimeException
: 후손들은 특별히 예외처리하지 않아도 자바가 예외처리를 해 줍니다
그러나 후손이 아니라면 사용자가 반드시 예외처리 해줘야 합니다
* java.io 에 있는 입출력관련
* java.net 에 있는 네트워크관련
* java.sql 에 있는 데이터베이스관련
위의 패키지들에 있는 대부분의 클래의 생성자와 메소드들은 예외를 갖고있으며
그것은 RuntimeException의 후손이 아니에요
그래서 반드시 예외처리를 해야합니다
throws IOException - IOException 안에 RuntimeException은 없다
/FileWriter 예외처리 하기/
import java.io.FileWriter;
class FileWriterTest {
public static void main(String[] args) {
FileWriter fw = new FileWriter("c:/data/hello.txt");
// 파일 내용 쓰기
fw.write("hello java");
// 파일 닫기
fw.close();
System.out.println("파일을 생성하였습니다.");
}
}
/*
javac FileWriterTest.java
FileWriterTest.java:5: error: unreported exception IOException; must be caught or declared to be thrown
FileWriter fw = new FileWriter("c:/data/hello.txt");
^
FileWriterTest.java:8: error: unreported exception IOException; must be caught or declared to be thrown
fw.write("hello java");
^
FileWriterTest.java:10: error: unreported exception IOException; must be caught or declared to be thrown
fw.close();
^
3 errors
*/
import java.io.FileWriter;
class FileWriterTest02 {
public static void main(String[] args) {
try{
FileWriter fw = new FileWriter("c:/data/hello.txt");
fw.write("hello java");
fw.close();
System.out.println("파일을 생성하였습니다.");
}catch(Exception e){
System.out.println("예외발생");
}
}
}
/e.getMessage()/
import java.io.FileWriter;
class FileWriterTest02 {
public static void main(String[] args) {
try{
// FileWriter fw = new FileWriter("c:/data/hello.txt");
// 없는 폴더에 실행하기
FileWriter fw = new FileWriter("c:/daka/hello.txt");
fw.write("hello java");
fw.close();
System.out.println("파일을 생성하였습니다.");
}catch(Exception e){
System.out.println("예외발생 : " + e.getMessage());
}
}
}
/e/
import java.io.FileWriter;
class FileWriterTest03 {
public static void main(String[] args) {
try{
FileWriter fw = new FileWriter("c:/daka/hello.txt");
fw.write("hello java");
fw.close();
System.out.println("파일을 생성하였습니다.");
}catch(Exception e){
// java.io.FileNotFoundException: c:\daka\hello.txt (지정된 경로를 찾을 수 없습니다)
System.out.println("예외발생 : " + e);
}
}
}
/메소드 안에서 예외처리/
import java.io.FileWriter;
class FileWriterTest04 {
// 파일 출력 담당을 pro에게 맡긴다
public static void pro(String fname) {
try{
FileWriter fw = new FileWriter(fname);
fw.write("hello java");
fw.close();
System.out.println("파일을 생성하였습니다.");
}catch(Exception e){
System.out.println("예외발생 : " + e);
}
}
public static void main(String[] args) {
pro("c:/daka/hello.txt");
}
}
/예외처리 호출하기/
import java.io.FileWriter;
import java.io.IOException;
class FileWriterTest05 {
public static void pro(String fname) throws IOException {
FileWriter fw = new FileWriter(fname);
fw.write("hello java");
fw.close();
System.out.println("파일을 생성하였습니다.");
}
public static void main(String[] args) {
try{
pro("c:/daka/hello.txt");
}catch(IOException e){
// System.out.println("예외발생 : " + e.getMessage());
System.out.println("예외발생 : " + e);
}
}
}
/하드웨어 물리적 오류 추적하기/
import java.io.FileWriter;
import java.io.IOException;
class FileWriterTest06 {
public static void pro(String fname) throws IOException {
FileWriter fw = new FileWriter(fname);
fw.write("hello java");
fw.close();
System.out.println("파일을 생성하였습니다.");
}
public static void main(String[] args) {
try{
pro("c:/daka/hello.txt");
}catch(IOException e){
// 예외가 발생하면 어디에서 문제가 발생하였는지 추적해가면서 정보를 출력
e.printStackTrace();
}
}
}
14:00 ~
<< 사용자 정의 예외 >>
자바는 대부분의 일반적인 예외에 대하여 이미 클래스로 만들어져있고
그러한 상황이되면 자동으로 예외 객체를 생성 해 줍니다
그런데 만약 내가 만들고있는 시스템에서만 특별한 상황이되면
"예외"로 만들고자 한다면 "사용자 정의 예외"를 만들 수 있고
그러한 상황이되어도 자바는 예외인줄 모르기 때문에 직접 예외 객체를 생성해야 합니다
그때 사용하는 명령이 throw입니다
throw new 사용자정의예외(); // 강제로 예외 생성
라고 하여 사용자정의예외 객체를 생성할 수 있어요
(throw와 throws를 비교해서 설명하시오.)
- 두 수의 조화평균,, 공식,,,
import java.util.Scanner;
class HarmonicMeanTest01 {
public static void main(String[] args) {
// 사용자한테 두 수를 입력받아 "조화평균"을 구하여 출력
Scanner sc = new Scanne(System.in);
int a, b, mean;
System.out.print("첫번째 수 : ");
a = sc.nextInt();
System.out.print("두번째 수 : ");
b = sc.nextInt();
mean = (2*a*6) / (a+b);
System.out.println("두 수의 조화평균은 : " + mean);
}
}
import java.util.Scanner;
// 조화평균이 있을 수 없는 사용자 정의 예외를 만들어 봅시다
class NotHarmonicMeanException extends Exception{
public NotHarmonicMeanException(String message){
super(message);
}
}
class HarmonicMeanTest02 {
public static void main(String[] args) {
try{
Scanner sc = new Scanner(System.in);
int a, b, mean;
System.out.print("첫번째 수 : ");
a = sc.nextInt();
System.out.print("두번째 수 : ");
b = sc.nextInt();
if (a == -b){
throw new NotHarmonicMeanException(a + "와" + b + "의 조화평균");
}
mean = (2*a*6) / (a+b);
System.out.println("두 수의 조화평균은 : " + mean);
}catch(NotHarmonicMeanException e){
System.out.println("예외발생 : " + e.getMessage());
}
}
}
/PROGRAMMING/
/*
PROGRAMMING 1.
숫자를 저장하고 있는 배열을 받아서~
*/
import java.util.Scanner;
import java.util.ArrayList;
// 사용자 정의 예외 class
class NotFoundException extends Exception {
public NotFoundException(String message){
super(message);
}
}
class SearchArray{
// 생성자, throws 강제 예외 시키기
public SearchArray(int[] arr, int value) throws NotFoundException {
int i;
ArrayList<Integer> list = new ArrayList<Integer>();
for(i = 0; i < arr.length; i++){
if(arr[i] == value){
list.add(i);
}
}
if(list.size() == 0){
// System.out.println("찾고자하는 데이터 " + value + "는 배열에 없어요.");
// 강제로 예외 발생시키기
throw new NotFoundException("찾고자하는 데이터 " + value + "는 배열에 없어요.");
}else{
System.out.println("찾고자하는 데이터 " + value + "는 인덱스 " + list + "에 있어요.");
}
}
}
class SearchArrayTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] data = {10,20,30,40};
System.out.print("배열에서 찾고자하는 값 : ");
int value = sc.nextInt();
try{
new SearchArray(data, value);
}catch(NotFoundException e){
System.out.println("예외발생 : " + e.getMessage());
}
}
}
System.out.println("찾고자하는 데이터 " + value + "는 배열에 없어요.");
throw new NotFoundException("찾고자하는 데이터 " + value + "는 배열에 없어요.");
출력문으로 메세지를 출력하면되는데 왜 굳이 "사용자정의예외"를 만들어요?
: 그냥 출력문을 써도됩니다
우리가 만들고자 하는 시스템에서 사용자의 요청에따라 발생할 수 있는 문제의 상황을
미리 만들어놓고 분명하게 하는것이 목적입니다
/*
PROGRAMMING 3.
은행 예금을 나타내는 클래스 BankAccount를 작성하라.
*/
package com.kosta.exam01;
public class NegativBalanceException extends Exception {
public NegativBalanceException(String message) {
super(message);
}
}
package com.kosta.exam01;
public class BankAccount {
private int balance;
public void deposit(int amount){ // 입금
balance = balance + amount;
System.out.println(amount + "원 입금하여 잔액 : " + balance);
}
public void withdraw(int amount) throws NegativBalanceException { // 출금
if(amount > balance){
throw new NegativBalanceException("잔액이 부족합니다. 잔액 : " + balance +
", 인출액 : " + amount);
}
balance = balance - amount;
System.out.println(amount + "원 인출하여 잔액 : " + balance);
}
public BankAccount() {
super();
// TODO Auto-generated constructor stub
}
public BankAccount(int balance) {
super();
this.balance = balance;
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
}
package com.kosta.exam01;
public class BankAccountTest {
public static void main(String[] args) {
try {
BankAccount b = new BankAccount(1000);
System.out.println("잔액 : " + b.getBalance());
b.deposit(1000);
System.out.println("잔액 : " + b.getBalance());
b.withdraw(400);
System.out.println("잔액 : " + b.getBalance());
b.withdraw(2000);
System.out.println("잔액 : " + b.getBalance());
}catch (NegativBalanceException e) {
e.printStackTrace();
}
}
}
/사용자한테 입력받기/
package com.kosta.exam03;
import java.time.temporal.TemporalAmount;
import java.util.Scanner;
public class BankAccountTest {
public static void menu() {
System.out.println("[1] 입금 [2] 출금 [3] 잔액조회 [0] 종료");
System.out.println("메뉴를 선택하시오 : ");
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
BankAccount account = new BankAccount();
int sel;
int amount;
System.out.println("** 은행에 방문하신 것을 환영합니다 **");
try {
while(true) {
menu();
sel = sc.nextInt();
if(sel == 0) {
break;
}
switch (sel) {
case 1:
System.out.print("입금 : ");
amount = sc.nextInt();
account.deposit(amount);
break;
case 2:
System.out.print("출금 : ");
amount = sc.nextInt();
account.withdraw(amount);
break;
case 3:
System.out.println("잔액 : " + account.getBalance());
break;
}
}
}catch (NegativBalanceException e) {
// e.printStackTrace();
System.out.println("예외발생 : " + e.getMessage());
}
}
}
ㅁㅔ뉴가 계속 나왔으면 좋겠어서ㅓ,, 질문했다가,,, finally하면 된다고 하셨다
절대 졸아서 기억못한게 아니당 ............
/예외가 발생한 후 계속 실행하고 싶다면 finally를 수행한다/
}finally { // 문제가 발생한 후 수행한다
menu();
sel = sc.nextInt();
}
/*
PROGRAMMING 4.
날짜를 나타내는 MyDate 클래스를 작성하여 보자.
*/
package com.kosta.exam04;
import java.lang.ProcessHandle.Info;
import java.util.Scanner;
import java.util.StringTokenizer;
class IlleagalArgumentException extends Exception{
public IlleagalArgumentException(String message) {
super(message);
}
}
class MyDate{
public MyDate(String str) throws IlleagalArgumentException {
Scanner sc = new Scanner(System.in);
String year, month, date;
System.out.print("YEAR/MONTH/DATE : ");
str = sc.nextLine();
StringTokenizer st = new StringTokenizer(str, "/");
if(st.countTokens() != 3) {
throw new IlleagalArgumentException("형식에 맞춰 입력해주세요.");
}
year = st.nextToken();
System.out.println("YEAR: " + year);
month = st.nextToken();
System.out.println("MONTH : " + month);
date = st.nextToken();
System.out.println("DATE : " + date);
}
}
public class MyDateTest {
public static void main(String[] args) {
try {
MyDate m = new MyDate("");
} catch (IlleagalArgumentException e) {
System.out.println("예외발생 : " + e.getLocalizedMessage());
}
}
}
이거눈 내 코드에서 chatGPT가 보완해준 방법 ~!~!
package com.kosta.exam04;
import java.util.StringTokenizer;
class IlleagalArgumentException extends Exception {
public IlleagalArgumentException(String message) {
super(message);
}
}
class MyDate {
public MyDate(String info) throws IlleagalArgumentException {
StringTokenizer st = new StringTokenizer(info, "/");
if (st.countTokens() != 3) {
throw new IlleagalArgumentException("Input format must be YEAR/MONTH/DATE");
}
String year = st.nextToken();
String month = st.nextToken();
String date = st.nextToken();
System.out.println("YEAR: " + year);
System.out.println("MONTH : " + month);
System.out.println("DATE : " + date);
}
}
public class MyDateTest {
public static void main(String[] args) {
try {
// 사용자로부터 입력 받기
java.util.Scanner scanner = new java.util.Scanner(System.in);
System.out.print("Enter YEAR/MONTH/DATE: ");
String input = scanner.nextLine();
// MyDate 객체 생성
MyDate m = new MyDate(input);
} catch (IlleagalArgumentException e) {
System.out.println("예외발생 : " + e.getMessage());
}
}
}
- 오늘 학습한 내용에 대하여 요약정리하고 궁금한 점 질문합니다
- pdf "예외처리"의 PROGRAMMING 4번을 완성 해 봅니다
- pdf "예외처리"의 2번도 작성 해 봅니다
'📖' 카테고리의 다른 글
day 0530 멀티쓰레드_임계영역_쓰레드사이의 통신 (0) | 2024.05.30 |
---|---|
day 0529 멀티쓰레드 (1) | 2024.05.29 |
day 0527 문자열 (0) | 2024.05.27 |
day 0524 컬렉션_가위바위보_그림판 (0) | 2024.05.24 |
day 0523 컬렉션 (0) | 2024.05.23 |