Why Doesn't Java Allow to Throw a Checked Exception from Static Initialization Block

Why doesn't Java allow to throw a checked exception from static initialization block?

Because it is not possible to handle these checked exceptions in your source. You do not have any control over the initialization process and static{} blocks cannot be called from your source so that you could surround them with try-catch.

Because you cannot handle any error indicated by a checked exception, it was decided to disallow throwing of checked exceptions static blocks.

The static block must not throw checked exceptions but still allows unchecked/runtime-exceptions to be thrown. But according to above reasons you would be unable to handle these either.

To summarize, this restriction prevents (or at least makes it harder for) the developer from building something which can result in errors from which the application would be unable to recover.

Can static code blocks throw exceptions?

From JLS §11.2.3:

It is a compile-time error if a class variable initializer (§8.3.2) or static initializer (§8.7) of a named class or interface can throw a checked exception class.

For completeness, an unchecked exception is defined in JLS §11.1.1:

RuntimeException and all its subclasses are, collectively, the run-time exception classes.

The unchecked exception classes are the run-time exception classes and the error classes.

This is the only type of exception that can be thrown from a static initializer.

use try catch in static initialization block

The static block must not throw checked exceptions but still allows unchecked/runtime-exceptions to be thrown.

That said, there's nothing inherently wrong about using a try catch in a static block. As stated above, this is actually a requirement if the code throws a checked exception.

why the static initializer cannot throw expetion

Static initializers can't throw checked exceptions, because initialization of a class can happen at effectively arbitrary places in the code at which point the checked exception would not be expected.

Static initializers can throw unchecked exceptions, which will prevent the class from being initialized correctly and will prevent the class from being used. Doing that will lead to terribly hard to debug problems, however.

The rule for this is in §8.7 Static Initializers of the JLS:

It is a compile-time error for a static initializer to be able to complete abruptly (§14.1, §15.6) with a checked exception (§11.2).

Why is it not allowed to throw an exception in a Java instance initialization block?

initializer must be able to complete normally

means that there must be a possible code path that doesn't throw an exception. Your examples unconditionally throw, and are therefore rejected. In the other examples, the static analysis doesn't go far enough to determine that they also throw in all cases.

For example,

public class StaticThrow {
static int foo = 0;
{{ if (Math.sin(3) < 0.5) { throw new ArithmeticException("Heya"); } else { foo = 3; } }}
public static void main(String[] args) {
StaticThrow t = new StaticThrow();
System.out.println(StaticThrow.foo);
}
}

compiles, and when run throws

Exception in thread "main" java.lang.ArithmeticException: Heya
at StaticThrow.<init>(StaticThrow.java:3)
at StaticThrow.main(StaticThrow.java:5)

Can initializer block throw exception?

An initializer block can only throw unchecked exceptions, or checked exceptions which are declared to be thrown by all constructors. (This includes exceptions which are subclasses of those which are declared.)

You can't throw a checked exception from an initializer in a class with no declared constructors, as you'll effectively be provided with a parameterless constructor which doesn't declare that it throws anything.

From section 11.2.3 of the JLS:

It is a compile-time error if an instance variable initializer or instance initializer of a named class can throw a checked exception class unless that exception class or one of its superclasses is explicitly declared in the throws clause of each constructor of its class and the class has at least one explicitly declared constructor.

How to handle a static final field initializer that throws checked exception

If you don't like static blocks (some people don't) then an alternative is to use a static method. IIRC, Josh Bloch recommended this (apparently not in Effective Java on quick inspection).

public static final ObjectName OBJECT_NAME = createObjectName("foo:type=bar");

private static ObjectName createObjectName(final String name) {
try {
return new ObjectName(name);
} catch (final SomeException exc) {
throw new Error(exc);
}
}

Or:

public static final ObjectName OBJECT_NAME = createObjectName();

private static ObjectName createObjectName() {
try {
return new ObjectName("foo:type=bar");
} catch (final SomeException exc) {
throw new Error(exc);
}
}

(Edited: Corrected second example to return from method instead of assign the static.)



Related Topics



Leave a reply



Submit