Exception and initialization block checked

According to JLS: this is a compile-time error if an instance variable initializer or an instance initializer of a named class can raise a checked exception class, unless this exception class or one of its superclasses is explicitly declared in the throws clause, each constructor of its class and class has at least one explicitly declared constructor.

So, if I do this -

class A{ { throw new FileNotFoundException(); } public A() throws IOException{ // TODO Auto-generated constructor stub } } 

This gives a compile time error. "The initializer should complete normally."

but

 class A{ { File f=new File("a"); FileOutputStream fo=new FileOutputStream(f); fo.write(3); } public A() throws IOException{ // TODO Auto-generated constructor stub } } 

This code does not display a compile-time error. Why doesn't the previous code compile even if I declared a throw clause in the constructor?

+7
source share
3 answers

There must be some condition where the initializer can actually exit without any exceptions.

In your case, there is no way this can happen.

Try:

 if(/*condition-to-fail*/) { /*Not always, only when something is wrong. Compiler knows that.*/ throw new FileNotFoundException(); } 

Update:

The following statement throws an exception.

 throw new FileNotFoundException(); 

So, without any conditions, the execution of your program always ends.

While in the next -

 FileOutputStream fo = new FileOutputStream(f); 

the FileOutputStream(File) constructor does not always throw this exception.

The throws clause in public FileOutputStream(File file) throws FileNotFoundException only means that it can throw this exception and it will be executed only if the file cannot be found otherwise at run time.

+4
source

http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.6

This is a compile-time error if the instance initializer cannot complete normally.

http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21

A non-empty block that is not a switch block can complete normally if the last statement in it can complete normally.

...

The if statement, regardless of whether it has an else part, is handled in an unusual way. For this reason, this is discussed separately at the end of this section.

...

so that the if statement can be used for conditional compilation purposes, the actual rules are different.

...

+2
source

In the first compiler, Case already knows that the instance initializer will never FileNotFoundException normally, because you explicitly selected FileNotFoundException there. You can say this is a smart compiler code evaluation. But if you make the compiler believe that the instance initializer has at least the slightest chance of shutting down, then the compiler will not complain at compile time. For example, in the code below, although the IDonotexist.txt file IDonotexist.txt not exist in my directory, and I'm sure it will throw a FileNotFoundException , but still the compiler will let it compile it successfully. Why? Since the presence of the file is checked at runtime, not at compile time.

 class A { { FileReader fr = new FileReader(new File("IDonotexist.txt")); } public A() throws IOException { // TODO Auto-generated constructor stub } public static void main(String st[])throws Exception { A a = new A(); } } 

This is similar to the case of initializing a final variable. For example, in the following code, the compiler will show a compile-time error

 public void calling() { final int i; int k = 90; if ( k == 90) { i = 56; } System.out.println(i);//Compiler will show error here as: variable i might not have been initialized } 

But if I replaced the condition if ( k == 90) with if(true) , then the compiler will not show an error. Since the compiler now knows that i will definitely be assigned some value.

+1
source

All Articles