/ / Dlaczego Java nie pozwala na wyrzucenie sprawdzonego wyjątku z bloku inicjalizacji statycznej? - Java, wyjątek, inicjator statyczny

Dlaczego Java nie pozwala na przesłanie sprawdzonego wyjątku z bloku inicjalizacji statycznej? - Java, wyjątek, inicjator statyczny

Dlaczego "Java" nie pozwala na przesłanie sprawdzonego wyjątku ze statycznego bloku inicjującego? Jaki był powód tej decyzji projektowej?

Odpowiedzi:

100 za odpowiedź № 1

Ponieważ nie można ich obsłużyćsprawdzone wyjątki w Twoim źródle. Nie masz żadnej kontroli nad procesem inicjowania, a statyczne {} bloki nie mogą być wywołane ze źródła, dzięki czemu możesz je otoczyć za pomocą try-catch.

Ponieważ nie można obsłużyć żadnego błędu wskazanego przez zaznaczony wyjątek, zdecydowano, że nie wolno rzucać sprawdzanych wyjątków bloków statycznych.

Blok statyczny nie może rzucać sprawdzone wyjątków, ale nadal umożliwia wyrzucanie wyjątków niezaznaczonych / wykonawczych. Ale zgodnie z powyższymi powodami nie byłbyś w stanie sobie z nimi poradzić.

Podsumowując, to ograniczenie zapobiega (lub przynajmniej utrudnia) programistom budowanie czegoś, co może skutkować błędami, z których aplikacja nie byłaby w stanie odzyskać.


59 dla odpowiedzi № 2

Możesz obejść problem, łapiąc każdy zaznaczony wyjątek i ponownie rzucając go jako niezaznaczony wyjątek. Ta niezaznaczona klasa wyjątków działa również jako opakowanie: java.lang.ExceptionInInitializerError.

Przykładowy kod:

protected static class _YieldCurveConfigHelperSingleton {

public static YieldCurveConfigHelper _staticInstance;

static {
try {
_staticInstance = new YieldCurveConfigHelper();
}
catch (IOException | SAXException | JAXBException e) {
throw new ExceptionInInitializerError(e);
}
}
}

19 dla odpowiedzi nr 3

Musiałoby to wyglądać tak (to jest nie prawidłowy kod Java)

// Not a valid Java Code
static throws SomeCheckedException {
throw new SomeCheckedException();
}

ale jak reklama go złapie? Sprawdzone wyjątki wymagają złapania. Wyobraź sobie kilka przykładów, które mogą zainicjować klasę (lub nie dlatego, że zostały już zainicjalizowane), i tylko po to, aby zwrócić uwagę na złożoność tego, co wprowadziłabym, umieściłem przykłady w innym statycznym initalizerze:

static {
try {
ClassA a = new ClassA();
Class<ClassB> clazz = Class.forName(ClassB.class);
String something = ClassC.SOME_STATIC_FIELD;
} catch (Exception oops) {
// anybody knows which type might occur?
}
}

I kolejna paskudna rzecz -

interface MyInterface {
final static ClassA a = new ClassA();
}

Wyobraź sobie, że ClassA miał statyczny inicjator rzucaniasprawdzony wyjątek: w tym przypadku MyInterface (który jest interfejsem z "ukrytym" inicjatorem statycznym) musiałby wyrzucić wyjątek lub obsłużyć go - obsługa wyjątków w interfejsie? Lepiej zostaw to takie, jakie jest.


4 dla odpowiedzi № 4

Spójrz na Specyfikacje języka Java: stwierdza się, że jest to błąd czasu kompilacji w przypadku inicjatora statycznego zawiedzie jest w stanie ukończyć gwałtownie z zaznaczonym wyjątkiem.


2 dla odpowiedzi № 5

Ponieważ żaden napisany kod nie może wywołać bloku inicjalizacji statycznej, nie jest użyteczne wyrzucanie sprawdzane exceptions. Gdyby było to możliwe, co zrobiłby jvm, gdy rzucono sprawdzone wyjątki? Runtimeexceptions są propagowane w górę.


-3 dla odpowiedzi № 6

Mogę skompilować wyrzucanie sprawdzonego wyjątku również ....

static {
try {
throw new IOException();
} catch (Exception e) {
// Do Something
}
}