[211122] 교육 22일차

oxllz·2022년 1월 31일
0

교육

목록 보기
16/41

예외처리

class 배째기 extends RuntimeException {}
class 등따기 extends RuntimeException {}
//
class 신입 {
	/*
		시간당 7천 이하일때는 30% 확률로 배를 째고
		5천 이하일때는 50% 확률로 등을따는 일이 생긴다는 것을 코드로 짜 보면??
	*/
	public void( int 시간당 ) {
		System.out.println("넹넹...");
		double rand = Math.random();
		if( rand < 0.3 && 시간당 < 7 ) {
			throw new 배째기();
		}
		else if ( rand < 0.7 && 시간당 < 5 ) {
			throw new 등따기();
		}
	}
}
//
public class Test174 {
	public static void main( String[] args ) {
		신입 kim = new 신입();
		try {
			kim.( 4 );
		}
		catch( 배째기 e ) {
			System.out.println("꿰맨다");
		}
		catch( 등따기 e ) {
			System.out.println("119 콜");
		}
	}
}

예외처리 : 프로그램 동작시의 오류를 처리하는 방법

  1. 함수가 호출될때 오동작은 발생한다.
  2. 각종 예외상황은 클래스로 정의된다. ( extends RuntimeException )
  3. 예외상황이 발생되면 해당 예외상황에 해당하는 클래스의 인스턴스를 만들고 그것을 던진다. ( throw new 인스턴스(); )
  4. 던져진 예외는 catch 되지 않으면 프로그램은 종료된다.
    ( 오동작이 발생하면 그에 대한 처리를 하지 않으면 프로그램은 종료 )
  5. 적절히 처리된 오동작은 마치 없었다는 듯이 프로그램은 수행을 계속한다.

try~catch

오동작 가능성이 있는 함수호출하는 영역을 try { ... } 로 감싸주고 ... 안에서 배째기가 벌어졌을때 처리하는 코드는 catch( 배째기 e ) { ... } 에 둔다.
등따기가 벌어졌을때 처리하는 코드는 catch( 등따기 e ) { ... } 에 둔다.

class 배째기 extends RuntimeException {}
class 등따기 extends RuntimeException {}
//
class 신입 {
	public void( int 시간당 ) {
		System.out.println("넹넹...");
		double rand = Math.random();
		if( rand < 0.3 && 시간당 < 7 ) {
			throw new 배째기();
		}
		else if ( rand < 0.7 && 시간당 < 5 ) {
			throw new 등따기();
		}
		System.out.println("끝났습니다");
	}
}
//
public class Test175 {
	public static void main( String[] args ) {
		신입 kim = new 신입();
		kim.( 4 );
		System.out.println("수고했습니다");
	}
}

try ~ catch 없어도 컴파일은 된다. 물론 실행하다 에러나면 프로그램은 죽지만 예외가 발생하면 그 이하의 코드는 수행하지 않는다 - 거기서 프로그램은 끝난다.


Exception

class 배째기 extends Exception {}
class 등따기 extends Exception {}
//
class 신입 {
	// 해당예외를 발생시킬 수 있음을 선언부에 명시한 코드 
	public void( int 시간당 ) throws 배째기, 등따기 { }
}
//
public class Test176 {
	public static void main( String[] args ) {
		신입 kim = new 신입();
		try {
			kim.( 4 );
			System.out.println("수고했습니다");
		}
		catch( 배째기 e ) {
			System.out.println("꿰맨다");
		}
		catch( 등따기 e ) {
			System.out.println("119");
		}
		System.out.println("오늘업무 끝");
	}
}

RuntimeException : 문법적으로 널널하다 ,
Exception 문법적으로 엄격하다

Exception 을 상속받은 예외를 발생할 수 있는 함수는 선언부에 반드시 그 사실을 명시해야 한다. ( RuntimeException 은 해도 되고 안해도 되고 ) : throws 배째기, 등따기

선언부에 예외발생 가능성이 명시된 함수는 호출시에 반드시 해당 에러를 처리할 수 있는 try ~ catch 영역 안에서 호출해야 한다.

try {
	kim.( 4 );
	System.out.println("수고했습니다");
}
catch( Exception e ) {
	System.out.println("통합대책 " + e.getClass().getName() );
}

배째기와 등따기 모두에 대해서 동작한다.
Exception e = new 배째기() or new 등따기(); 이 가능하면 잡는다.
즉 "catch 에 선언된 매개변수(?)가 throw 한 예외 인스턴스를 가리킬 수 있을때 잡는다."


Throwable

catch( Throwable e ) {
	System.out.println("통합대책 " + e.getClass().getName() );
}
``

ThrowableException 의 부모클래스이다.

예외상황이 아닌 경우에도 try catch 를 이용한 코드를 만들어야 할 때가 있어서 모든 try catch 를 쓰는 경우는 Throwable 로 상속받고 , 그중의 예외상황은 Exception 을 상속받고 ,
RuntimeExceptionException 을 상속받는다 ( 널널한 예외 )

  • Throwable ( 왕조상 ) - Exception ( 조상 ) - RuntimeException

finally

try { }
catch( Exception e ) { }
finally { }

try 에서 예외가 발생하건 발생하지 않건 무조건 실행하는 영역


import static

package banana;
import static banana.Temp.print;
//
class Temp {
	public static void print() {
		System.out.println("print");
	}	
}
//
public class Test184 {
	public static void main( String[] args ) {
		print();
	}
}

static import 는 대상이 class 가 아니라 class 안에 선언된 static 함수이고 마치 c 에서 함수호출 하듯이 static 한 함수를 함수명만으로 호출 할 수 있다.


OutputStream

public class Test185 {
	public static void main( String[] args ) {
		OutputStream out = null;
		try {
			out = new FileOutputStream("C:\\JavaWork\\a.dat");	
			out.close();
		}
		// catch( FileNotFoundException e ) { }
		catch( IOException e ) { }
}

FileNotFoundException extends IOException 이기에
catch( IOException e ) {} 하나만 배치해도 문제 없다.

public class Test187 {
	public static void main( String[] args ) {
		try {
			OutputStream out = new FileOutputStream("C:\\JavaWork\\a.dat");	
			out.write( 100 );
			out.write( 101 );
			out.write( 123456 );
			out.close();
		}
		catch( IOException e ) {
			System.out.println( e );
		}
	}
}

FileOutputStream : 해당 파일에 정보를 기록하게 해 주는 클래스
write : 한번 호출할때 한바이트씩 기록 ( int 는 32비트인데? - 32비트 중 하위 8비트만 기록 )
close : 다 끝나면 호출해준다.


InputStream

public class Test188 {
	public static void main( String[] args ) {
		try {
			InputStream in = new FileInputStream("C:\\JavaWork\\a.dat");
			int a = in.read(); 
			int b = in.read(); 
			int c = in.read(); 
			int d = in.read();
			in.close();
			//
			System.out.println( a ); // 100
			System.out.println( b ); // 101
			System.out.println( c ); // 64 (256 넘는 값은 저장하면서 잘림)
			System.out.println( d ); // 읽을게 없어서 -1
		}
		catch( IOException e ) {
			System.out.println( e );
		}
	}
}

OutputStream 에 void write( int ) 가 있으면
InputStream 에는 int read() 가 있다.

순서대로 write 된 내용을 순서대로 read 하는 형태로 동작하고 있다. 순서대로 읽다가 더 이상 읽을 것이 없을때는 -1 이 리턴된다. ( Test187 코드와 연동해서 이해)

public class Test189 {
	public static void main( String[] args ) {
		try {
			InputStream in = new FileInputStream("C:\\JavaWork\\a.dat");
			// 이 코드는 반드시 암기할 것!!!
			int r = 0;
			while( ( r = in.read() ) != -1 ) {
				System.out.println( r );
			}
			in.close();
		}
		catch( IOException e ) {
			System.out.println( e );
		}
	}
}

in.read() 한 값이 -1 이 아닐때까지 while 문이 동작한다.

이해를 돕기위한 코드

boolean alive = true;
while( alive ) {
	int r = in.read();
	if( r == -1 ) {
		alive = false;
	} else {
		System.out.println( r );
	}
}

0개의 댓글