Salil Misra
Salil Misra

Reputation: 86

Checked exception and initializer block

According to 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.

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 "initializer must complete normally"

while

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 doesn't show any compile time error. Why doesn't the previous code compile even if I have declared a throws clause in the constructor?

Upvotes: 7

Views: 596

Answers (3)

Bhesh Gurung
Bhesh Gurung

Reputation: 51030

There should be some condition when the initializer can actually complete without any exception.

In your case there is no way that it can happen.

Try:

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

Update:

The following statement is actually throwing the exception.

throw new FileNotFoundException(); 

So with no condition your program execution always ends there.

While in the following -

FileOutputStream fo = new FileOutputStream(f);

the constructor FileOutputStream(File) doesn't always throw that exception.

The throws clause in public FileOutputStream(File file) throws FileNotFoundException is only saying that it might throw that exception, and it will do it only if at runtime the file is not found otherwise not.

Upvotes: 4

Vishal K
Vishal K

Reputation: 13066

In first Case compiler is already knowing that the instance initializer is never going to complete normally because you have explicitly thrown FileNotFoundException over there. You can say it the smart code assessment of the compiler. But if you make the compiler to believe that the instance initializer has even a slightest chance of completing successfully then compiler won't complain while compilation. For example in the code given below although file IDonotexist.txt does not exist on my directory and I am sure that it would throw FileNotFoundException but still compiler would let it compile successfully . Why? Because the existence of file is checked during Execution of code , not while compilation.

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 final variable initialization. For Example in following code, the compiler will show 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 replace the condition if ( k == 90) with if(true) then compiler won't show error. Because compiler now knowing that i is definitely going to be assigned some value.

Upvotes: 1

irreputable
irreputable

Reputation: 45443

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

It is a compile-time error if an 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 iff the last statement in it can complete normally.

...

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

...

in order to allow the if statement to be used conveniently for "conditional compilation" purposes, the actual rules differ.

...

Upvotes: 2

Related Questions