본문으로 바로가기

예외 및 입출력 처리

category 프로그래밍/java 2017. 9. 11. 20:01

예외의 원리 




▶ 파일을 처리하는 프로그램을 실행시켰다. 그러나 지정한 파일을 발견할 수 없었다.

▶ 사용자가 입력한 문자열을 정수로 변환하는 프로그램을 실행. 그러나 사용자가 정수로 변환할 수 없는 문자열을 입력

▶ 배열을 처리하는 프로그램을 실행. 그러나 배열의 길이를 넘어서는 위치에 값 대입



java에서 이러한 프로그램 에서 예외처리를 위한 코드를 제공한다. 




public class Sample1 {


public static void main(String[] args) 

{

int[] test;

test = new int[5];

System.out.println("test[10]에 값을 대입합니다.");

test[10] = 80;

System.out.println("test[10]에 80을 대입했습니다. ");

System.out.println("무사히 종료했습니다.");

}

}


실행결과

test[10]에 값을 대입합니다.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10

at Sample1.main(Sample1.java:9)



배열의 첨자(test[10])가 배열의 길이를 넘어섰기 때문에 예외가 발생한 것이다. 

Java에서는 이러한 에럴를 일컬어 ArrayIndexOutOfBoundsException라는 종류의 예외가 발생했다고 부른ㄷ다

예외가 던져졌다(thrown)이라고 부르기도 합니다. 




public class Sample2 {


public static void main(String[] args) 

{

// TODO Auto-generated method stub

try 

{

int[] test;

test = new int[5];

System.out.println("test[10]에 값을 대입합니다.");

test[10] = 80;

System.out.println("test[10]에 80을 대입했습니다. ");

}

catch (ArrayIndexOutOfBoundsException e) { catch블록안에서 예외를 받는다.

                               배열 예외클래스  변수명 e

// TODO: handle exception

System.out.println("배열의 길이를 넘어섰습니다.");

}

System.out.println("무사히 종료했습니다.");

}


}


실행결과

test [10]에 값을 대입합니다.

배열 길이를 넘어섰습니다. catch 블록 안의 코드가 실행

무사히 종료했습니다.




구문

try

{

예외 발생을 조사할 문장

}

catch(예외 클래스 변수명 )

{

}

public class Appilcation {


public static void main(String[] args) {

// TODO Auto-generated method stub

int i = 10;

int j = 0;

try {

int k = i/j; //0으로 나눌때 예외발생을 시킨다.

} catch (ArithmeticException e) {

// TODO: handle exception

System.out.println("0으로 나눌수 없습니다." + e.toString());// 객체를 출력할때 toSting()메소드를 사용

}

System.out.println("main end");

}}



1.try블록안에서 예외가 발생하면 그 시점에서 코드의 실행을 중지
2. 발생된 예외의 종류가 catch 블럭의() 안에서 지정한 예외와 일치하면 그 안의 코드를 실행시킨다. 

3. catch 블록 안의 코드가 모두 실행되면 try~catch블록 다음에 코드를 실행시킨다.



finally 블록 추가하기

try

{

예외 발생을 조사할 문장

}

catch(예외 클래스 변수명 )

{

}

finally

{

마지막에 반드시 실행시켜야 하는 코드

}


Sample3 finally 블록 추가



public class Sample3 {


public static void main(String[] args) {

// TODO Auto-generated method stub

try

{

int [] test;

test = new int[5];

System.out.println("test[10]에 값을 대입합니다.");

test[10] = 80;

System.out.println("test[10]에 80울 대입합니다.");

}

catch(ArrayIndexOutOfBoundsException e)

{

System.out.println("배열 길이를 넘어섰습니다.");

}

finally

{

System.out.println("마지막에 반드시 이 코드가 실행됩니다.");

}

System.out.println("무사히 종료되었습니다.");

}


}

실행결과 


test[10]에 값을 대입합니다.

배열 길이를 넘어섰습니다. 예외처리된 catch블록 코드 실행

마지막에 반드시 이 코드가 실행됩니다. finally블록 코드가 실행

무사히 종료되었습니다.




예외와 클래스


예외란 클래스 라이브러리(java.lang 패키지)에 속한  Throwable 클래스를 확장한 서브 클래스의 객체를 뜻한다. 

지금까지 다룬 예제는 Throwabl 클래스의 서브 클래스를 확장한 ArrayIndexOutOfBoundsException이라는 클래스의 객체입니다. 



catch(ArrayIndexOutOfBoundsException e)

{

System.out.println("배열 길이를 넘어섰습니다.");

}


예외 정보 출력하기


class Sample4


{

    

public static void main(String[] args)

    

{

        

try{

            

int[] test;

            

test = new int[5];

            

            


System.out.println("test[10]에 값을 대입합니다.");

            

            


test[10] = 80;

            

System.out.println("test[10]에 80을 대입했습니다.");

        

}

        

catch(ArrayIndexOutOfBoundsException  e){ 예외를 받습니다. 

            

            


System.out.println("배열 길이를 넘어섰습니다.");

            

System.out.println(e + "이라는 예외가 발생했습니다.");  어떤 종류의 예외인지 출력한다. 

        

}

        

System.out.println("무사히 종료했습니다.");

    

}


}


test[10]에 값을 대입합니다.

배열 길이를 넘어섰습니다.

java.lang.ArrayIndexOutOfBoundsException: 10이라는 예외가 발생했습니다.  어떠한 종류의 예외인지 알 수 있다.

무사히 종료했습니다.


 Throwable  : 슈퍼 클래스 

Error                                Exception

ioException        RuntimeException

ArrayIndexOutofException


Error 클래스는 더 이상 프로그램의 실행시킬수 없음을 나타낸다.. 따라서 예외처리를 하지 않는 것이 일반적

ioException은 Exception 클래스의 서브클래스이며 키보드 입력 에러 발생시 생기는 예외


다양한 예외 클래스

catch(ArrayIndexOutOfBoundsException ae)

{

배열 길이를 넘어섰을때 경우 에러

}

catch(IOExcecption ie)

{

입출력 에러를 발생

}

catch(Exception e)

{

배열 범위 에러입출력 에러를 처리

}


예외 던지기(예외 클래스 선언하기)


자신만의 예외 클래스를 만들기 위해서는 Throwable 클래스의 서브 클래스를 확장한 예외 클래스를 선언해야 한다.

예을 들어 Excetion 클래스(Throwable 클래스의 서브 클래스)를 상속받아서 CarException라는 독자적인 예외 클래스를 작성해보자.


class CarException extends Exception

{

} Exception 클래스를 상속받아서 독자적인 예외 클래스를 선언한다.


예외 던지기

public void setCar(int n, double g) throws CarException //CarException클래스로부터 예외를 던지는 setCar메소드 선언

{

if(g<0)

CarException e = new CarException();

throw e;  생성된 예외 객체를 던진다. 

}

구문

throw 예외 객체를 가리키는 변수;

예외를 던지는 메소드

리턴 값의 형(type) 메소드(method) 명(인수 목록) throws 예외 클래스


Sample5 예외던지기


class CarException extends Exception


{


}


//자동차 클래스


class Car


{

    

private int num;

    

private double gas;

    

    


public Car ()

    

{

        

num = 0;

        

gas = 0.0;

        

System.out.println("자동차가 만들어졌습니다.");

    

}

    

public void setCar (int n, double g) throws CarException

    

{

        

if(g < 0){

            

CarException e = new CarException(); 객체생성

            

throw e; 예외를 던진다.

        

else {

            

num = n;

   gas = g;

            

System.out.println("차량 번호를 " + num + "으로, 연료 양을 " + gas + "로 바꾸었습니다.");

        

}

    

}

    

public void show()

    

{

        

System.out.println("차량 번호는 " + num + "입니다.");

        

System.out.println("연료 양은 " + gas + "입니다.");

    

}


}



class Sample5


{

    

public static void main(String[] args)

    

{

        

Car car1 = new Car();

        

try{

            

car1.setCar(1234, -10.0);

        

}

        

catch(CarException e){ setCar에서 만든 예외처리 클래스

            

System.out.println (e + "(이)가 던져졌습니다.");

        

}

        

car1.show();

    

}


}


/* class Sample5


{

    

public static void main(String[] args) throws CarException

   

{

        

Car car1 = new Car();

        

car1.setCar(1234, -10.0);

        

car1.show();

    

}




실행화면

자동차가 만들어졌습니다.

CarException(이)가 던져졌습니다.

차량 번호는 0입니다.

연료 양은 0.0입니다.



입출력의 기본


스트림의 원리 이해

 입력과 출력은 처리할 수 있도록 하는 기능을 제공하는데 문자열 스트림을 통해 이루어진다. 



스트림의 예


화면과 키보드로 입력하고 출력하기


import java.io.BufferedReader;  버퍼를 경유해 읽어 들이기 위한 문자 스트림

import java.io.IOException; 예외클래스

import java.io.InputStreamReader;  문자스트림 클래스


public class Sample6 {


public static void main(String[] args) {

// TODO Auto-generated method stub

System.out.println("문자열을 입력하십시오.");

try

{                                          2. 버퍼를 경유하여 읽어들인다.      1. 표준 입력을 사용하여 문자스트림 작성

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

String str = br.readLine();

System.out.println(str +"입력되었습니다.");

}

catch(IOException e)

{

System.out.println("입출력 에러가 발생되었습니다.");

}

}


}


실행화면

문자열을 입력하십시오.

hello

hello입력되었습니다.


이 코드에서는 화면에 출력하기 위해 표준 출력을 , 키보드를 통해 입력을 받기 위해 표준 입력(키보드)를 나타내는 객체를 사용했다.
System.out ... 표준 출력
System.in...  표준 입력


파일에 출력하기

Sample7.java 파일에 출력하기


import java.io.*;


public class Sample7 {


public static void main(String[] args) {

// TODO Auto-generated method stub

try {                                                                               1.파일 이름을 입력하여 표준 입력을 사용하기 

위한 문자스트림을 생성한다.

PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("test.txt")));

3.한줄씩 기록하기 위해 준비 2. 버퍼를 경유하여 읽어들인다.

pw.println("Hello"); 1줄씩 기록

pw.print("GoodBye");

System.out.println("파일에 기록되었습니다.");

pw.close(); 파일을 닫는다. 

}

catch(IOException e)

{

System.out.println("입출력에러가 발생되었습니다.");

}

}


}


FileWriter 클래스 파일에 기록하기 위한 문자 스트림

PrintWriter 한줄씩 기록하기 위한 문자 스트림

BufferedWriter 클래스 버퍼를 경유해서 기록하기 위한 문자 스트림


파일로 입력하기

import java.io.*;


public class Sample8 {


public static void main(String[] args) {

// TODO Auto-generated method stub

try {                                                                 파일을 읽어 들이는 문자 스트림 생성

BufferedReader br = new BufferedReader(new FileReader("test.txt"));

String str1 = br.readLine();  1행을 읽어 들인다. 

String str2 = br.readLine();



System.out.println("파일에 기록된 2개의 문자열은");

System.out.println(str1 + "입니다.");

System.out.println(str2 + "입니다.");

br.close();

}

catch(IOException e)

{

System.out.println("입출력 에러가 발생되었습니다.");

}

}


}


파일에 기록된 2개의 문자열은

Hello입니다.

GoodBye입니다.


FileReader 클래스 일을 읽어들이기 위한 문자 스트림

BufferedReader 클래스 버퍼를 경유해 읽어 들이기 위한 문자 스트림



많은 양의 데이터를 입력하기

text2.txt    

80

68

22

33

56

78

33

56

학생 8명의 시험 점수를 예를 들어 나타낸것.... 이렇게 많은 시험 데이터를 읽어들이는 코드를 작성해보자


import java.io.*;




class Sample9


{

    

public static void main(String[] args)

    

{

        

try{

            

BufferedReader br = new BufferedReader(new FileReader("test2.txt"));

            

            


int[] test = new int[8];

            

String str;

            

            


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

                

str = br.readLine();

                

test[i] = Integer.parseInt(str);

            

}

       

     

            

int max = test[0];

            

int min = test[0];

            

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

                

if( test[i]> max )

                    

max = test[i];

                

if( test[i] < min ) 

min = test[i];

                    

System.out.println(test[i]);

            

}

            

            


System.out.println("최고 점수는 " + max + " 입니다.");

            

System.out.println("최저 점수는 " + min + " 입니다.");

            

            


br.close();

        

}

        

catch(IOException e){

            

System.out.println("입출력 에러가 발생했습니다.");

        

}

    

}


}


실행결과


이클립스에서는 실행안됨 cmd로 컴파일해야함


80

68

22

33

56

78

33

56

최고 점수는 80 입니다.

최저 점수는 22 입니다.






명령 줄 인수를 사용하기


프로그램을 실행할 때 사용자가 읽고 쓰는 파일이름을 자유롭게 지정할 수 있다면 편리한 프로그램이 될 수 있다. 


명령줄 인수란 프로그램이 실행될 때 사용자로부터 입력 값을 받아 프로그램을 처리하는 방식
명령줄 인수는 다음과 같이 main()메소드의 인수로 정의되어 있다. 


구문 

public static void main(String[] args)

{

}

text3. txt


A long time ago,

There was a little girl.


Sample10.java


import java.io.BufferedReader;

import java.io.FileReader;

import java.io.IOException;


public class Sample10 { 이 프로그램을 실행할 때 프로그램 이름 뒤에 한 칸을 띄우고 문자열을 입력한다. 
                                가져올 파일 이름을 (text3.txt)을 입력한다. 명령 줄 인수를 사용하는 프로그램에서는 이 입력 문자열을 배열

  args로 다루도록 되어 있다.


public static void main(String[] args) {

// TODO Auto-generated method stub

if(args.length != 1)  배열 args의 길이를 조사한다.  그러니까 text3.txt파일이 하나인지 검사하는것이다. 

{

System.out.println("올바른 파일 이름을 입력하십시오"); 하나가 아닌경우 오류 메세지를 출력한다. 

System.exit(1); 조건과 다른 경우 프로그램을 종료한다. 

}

try {

BufferedReader br = new BufferedReader(new FileReader(args[0]));

 args[0]은 사용자가 지정한 파일 이름이다. 

String str;

while((str = br.readLine()) != null) 읽어들어서 str에 저장하고 계속 반복한다. 값이 null이 아니라면

{

System.out.println(str);

}

br.close();

}

catch(IOException e) {

System.out.println("입출력에러가 발생하였습니다.");

}

}


}


실행결과 이클립스에서 실행안됨 cmd로 컴파일해야함



A long time ago,

There was a little girl.



명령 줄인수


ex

Sample10 text.txt         Hello         Goodbye

             args[0]        args[1]         args[2]