среда, 1 августа 2012 г.

exceptions: throws + checked/unchecked

    Генерацию unchecked исключения не надо отражать в сигнатуре
public class ExceptionTest_ThrowThrows_0A {
    public static void main(String[] args) {
        throw new RuntimeException();
    }
}
public class ExceptionTest_ThrowThrows_0B {
    public static void main(String[] args) {
        throw new NullPointerException();
    }
}
public class ExceptionTest_ThrowThrows_0C {
    public static void main(String[] args) {
        throw new Error();
    }
}
public class ExceptionTest_ThrowThrows_0D {
    public static void main(String[] args) {
        throw new OutOfMemoryError();
    }
}

    Если генерацию checked исключения не отразить в сигнатуре, то будет ошибка времени компиляции
public class ExceptionTest_ThrowThrows_1A {
    public static void main(String[] args) { // ОШИБКА!
        throw new Exception();
    }
}
import java.io.IOException;

public class ExceptionTest_ThrowThrows_1B {
    public static void main(String[] args) { // ОШИБКА!
        throw new IOException();
    }
}
public class ExceptionTest_ThrowThrows_1C {
    public static void main(String[] args) { // ОШИБКА!
        throw new Throwable();
    }
}

    Если генерацию checked исключения (или его предка) отразить в сигнатуре, то ошибки времени компиляции не будет
public class ExceptionTest_ThrowThrows_2C {
    public static void main(String[] args) throws Throwable {
        throw new Throwable();
    }
}
public class ExceptionTest_ThrowThrows_2AA {
    public static void main(String[] args) throws Exception {
        throw new Exception();
    }
}
public class ExceptionTest_ThrowThrows_2AB {
    public static void main(String[] args) throws Throwable {
        throw new Exception();
    }
}
import java.io.IOException;

public class ExceptionTest_ThrowThrows_2BA {
    public static void main(String[] args) throws Exception {
        throw new IOException();
    }
}
import java.io.IOException;

public class ExceptionTest_ThrowThrows_2BB {
    public static void main(String[] args) throws Throwable {
        throw new IOException();
    }
}

    Мы имеем право отразить генерацию unckeched исключения в сигнатуре, не выбрасывая его. Единственный смысл - документирование того, что метод может выбрасывать такое исключение
public class ExceptionTest_ThrowThrows_3B {
    public static void main(String[] args) throws RuntimeException {
        // empty
    }
}

    Мы имеем право отразить генерацию checked исключения в сигнатуре, не выбрасывая его. Смысл - требуем уже сейчас включать код обработки такого исключения, а бросать можем позже
public class ExceptionTest_ThrowThrows_3A {
    public static void main(String[] args) throws Exception {
        // empty
    }
}

    Корректно отразить генерацию checked исключения более общего вида в сигнатуре, не выбрасывая его потомка. Смысл - требуем уже сейчас включать код обработки более "широкого" исключения
import java.io.IOException;

public class ExceptionTest_ThrowThrows_4A {
    public static void main(String[] args) throws Exception {
        throw new IOException();
    }
}
import java.io.IOException;

public class ExceptionTest_ThrowThrows_4B {
    public static void main(String[] args) throws Exception {
        if (args.length == 0) {
            throw new IOException();
        } else {
            throw new InterruptedException();
        }
    }
}

    Ничего не происходит
public class ExceptionTest_ThrowThrows_10A {
    public static void main(String[] args) {
        f();
    }
    private static void f() {}
}

    Unckeched исключения можно просто игнорировать
public class ExceptionTest_ThrowThrows_10B {
    public static void main(String[] args) {
        f();
    }
    private static void f() throws NullPointerException {}
}

    Ckeched исключения игнорировать не получится - ошибка компиляции
import java.io.IOException;

public class ExceptionTest_ThrowThrows_10C {
    public static void main(String[] args) { // ОШИБКА!
        f();
    }
    private static void f() throws IOException {}
}

    Нужно указать его тип
import java.io.IOException;

public class ExceptionTest_ThrowThrows_10D {
    public static void main(String[] args) throws IOException {
        f();
    }
    private static void f() throws IOException {}
}

    Или предка
import java.io.IOException;

public class ExceptionTest_ThrowThrows_10E {
    public static void main(String[] args) throws Exception {
        f();
    }
    private static void f() throws IOException {}
}
import java.io.FileNotFoundException;

public class ExceptionTest_ThrowThrows_10F {
    public static void main(String[] args) throws Exception {
        f();
        g();
    }
    private static void f() throws FileNotFoundException {}
    private static void g() throws InterruptedException {}
}

    Это можно "подавить", если перехватить исключение
public class ExceptionTest_ThrowThrows_20A {
    
    public static void main(String[] args) {
        try {
            f();
        } catch (Exception ignore) {
            // NOP
        }
    }

    private static void f() throws Exception {}
}

    Или заменить checked исключение на unchecked
public class ExceptionTest_ThrowThrows_20B {

    public static void main(String[] args) {
        try {
            f();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static void f() throws Exception {}
}

    Или заменить checked исключение на другой checked
import java.io.IOException;

public class ExceptionTest_ThrowThrows_20C {

    public static void main(String[] args) throws IOException {
        try {
            f();
        } catch (Exception e) {
            throw new IOException(e);
        }
    }

    private static void f() throws Exception {}
}

    Или заменить unchecked на checked
public class ExceptionTest_ThrowThrows_20D {

    public static void main(String[] args) throws Exception {
        try {
            f();
        } catch (NullPointerException e) {
            throw new Exception(e);
        }
    }

    private static void f() {}
}