개체 지향을 얘기하면 꼭 나오는 단어인 예외에 대해서 알아본다.
try {
// 시도할 코드들
} catch (<예외 클래스 1> <변수명>) { // 하나 이상 있을 수 있음
// 예외 처리 코드
} catch (<예외 클래스 2> <변수명>) {
// 예외 처리 코드
} finally { // 생략 가능
// 예외와 상관없이 항상 실행되는 코드
}
IOException
: 입출력 관련 클래스들의 부모 클래스EOFException
, FileNotFoundException
등ArithmeticException
: 산술과 관련된 예외 (0나누기)IndexOutOfBoundsException
Exception
클래스를 사용하면 다잡는다.defer
를 잘쓰면 되겠다. static void WriteByte(string path, byte b)
{
FileStream fs = null;
try
{
fs = File.Open(path, FileMode.Open);
fs.WriteByte(b);
}
catch (IOException e)
{
Console.Error.WriteLine($"{e.Message");
return;
}
}
string path;
WriteByte(path, 67);
WriteByte(path, 67); // 예외 발생
static void WriteByte(string path, byte b)
{
FileStream fs = null;
try
{
fs = File.Open(path, FileMode.Open);
fs.WriteByte(b);
fs.Close();
}
catch (IOException e)
{
Console.Error.WriteLine($"{e.Message");
fs.Close();
return;
}
}
Open
함수는 넘어갈 수 있지만, WriteByte()
함수에서 에러가 나버리면 곤란해진다.IOException
말고 다른 예외가 발생하면 Close
는 호출되지 않는다.static void WriteByte(string path, byte b)
{
FileStream fs = null;
try
{
fs = File.Open(path, FileMode.Open);
fs.WriteByte(b);
}
catch (IOException e)
{
Console.Error.WriteLine($"{e.Message");
return;
}
finally
{
if (fs != null)
{
fs.Close();
}
}
}
finally
이다.public void writeByte(String relativePath, byte b) {
Path path = Paths.get(getClassPath(), relativePath);
FileOutputStream out = null;
try {
out = new FileOutputStream(new File(path.toString()), true);
out.write(b);
out.close();
} catch (IOException e) {
e.printStackTrace();
return;
}
}
write
시 에러나면 close
안하고 나간다.FileOutputStream
개체를 해제 시킨다.finalize()
를 호출하는데 이 안에서 close()
를 호출한다.finalize()
를 삭제할 예정이라 함public void writeByte(String relativePath, byte b) {
Path path = Paths.get(getClassPath(), relativePath);
FileOutputStream out = null;
try {
out = new FileOutputStream(new File(path.toString()), true);
out.write(b);
out.close();
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
if out (out != null) {
out.close();
} catch (Exception e) {
}
}
}
try
블록 실행이 중단됨catch
블록 중에 발생한 예외를 처리할 수 있는 블록이 있는지 찾음catch
블록 안의 코드들을 실행finally
블록을 실행try
블록이후의 다른 코드들이 실행됨finally
를 블록을 실행try
블록으로 전달try {
} catch (IOException e) {
// 내가 처리 안하고 위에서 처리하고 싶어
throw e;
} catch (Exception e) {
} finally {
}
public final class UserNotFoundException extends RuntimeException {
public UserNotFoundException() {
super();
}
public UserNotFoundException(String message) {
super(message);
}
public UserNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
super
호출한 것으로 보아 RuntimeException
에도 같은 파라미터 받는 함수가 있을 것이란 것을 알 수 있음public static void main(String[] args) {
db.findUser("wansik")
}
public User findUser(String username) {
for (User user : users) {
if (user.getUsername().equals(username)) {
return user;
}
}
throw new UserNotFoundException(username) // 에러를 생성해서 던짐
}
RuntimeException
을 상속하여 사용한다고 함Exception
을 상속하여 사용할 수도 있다고 함public static void main() {
program.divide(10, 0); // Exception in thread "main" java.lang.ArithmeticException: / by zero
}
public int divide(int num, int denom) {
return num / denom;
}
main()
메서드까지 처리를 안해줄 경우 JVM이 오류를 띄우고 종료시킴