4

Why doesn't the compiler understand that the variable is initialized in either the try or the catch block and complains at the finally block?

int i;
try {
    i = 0;
}
catch (Exception e) {
    i = 2;
}
finally {
    System.out(i);
}
Frunk
  • 180
  • 1
  • 2
  • 11
forcewill
  • 1,637
  • 2
  • 16
  • 31

3 Answers3

5

If the initialization statement (i = 0;) fails, then the program will continue with the finally block, where the variable will still be un-initialized and this is why you get a compile-time error.

Konstantin Yovkov
  • 62,134
  • 8
  • 100
  • 147
  • Omg face palm off course the `finally` needs to be executed before the `catch` – forcewill Oct 17 '14 at 13:59
  • 1
    Why do you say the finally block will be preformed before the catch? http://stackoverflow.com/questions/3109353/what-comes-first-finally-or-catch-block – Ian2thedv Oct 17 '14 at 14:08
  • 1
    So according to http://stackoverflow.com/questions/3109353/what-comes-first-finally-or-catch-block `catch` should run before the `finally` then why does the compile complains – forcewill Oct 17 '14 at 14:20
  • Compiler complains because local variables should be declared and initialized at the same time but you have just declared it. –  Oct 17 '14 at 14:30
  • @user1203153 thats not true as far as i know http://docs.oracle.com/javase/specs/jls/se5.0/html/defAssign.html – forcewill Oct 17 '14 at 14:34
  • In your code, it complains at finally block just because you are trying to use a variable without being initialized. finally block doesn't know whether the variable is initialized or not due to its scope. Your above link proves my point. –  Oct 17 '14 at 14:43
  • Thanks, very informative link. So if compiler is sure about some statements it acts accordingly e.g. unreachable statement. In your case compiler knows it will surely execute the finally block, then any variable being used in this block should be already initialized. just put this code in your finally block above print statement to verify while (true) { i =1; if (i >= 5) break; } –  Oct 17 '14 at 15:10
  • What i think i was missing is that the compiler assumes that the `try`can fail but also the assignment in the `catch` can also fail therefore when reaching the `finally` its possible the variable wont be initialised is that it ? – forcewill Oct 17 '14 at 15:40
  • You're right, If you print variable 'i' in catch block before initialization, it gives error because compiler thinks that an exception might be thrown before 'i' has been set in try block in which case 'i' would not have been initialized so is the case with finally here i.e. when you print 'i' in finally block compiler thinks that an exception might be thrown before 'i' has been set in catch block in which case 'i' would not have been initialized –  Oct 17 '14 at 16:30
2

The compiler won't be able to know if i will get initialized or not. It might fail for whatever reason and therefor the finally block might not work.

Frunk
  • 180
  • 1
  • 2
  • 11
2

If you print variable 'i' in catch block before initialization, it gives error because compiler thinks that an exception might be thrown before 'i' has been set in try block in which case 'i' would not have been initialized so is the case with finally here i.e. when you print 'i' in finally block compiler thinks that an exception might be thrown before 'i' has been set in catch block in which case 'i' would not have been initialized

Compiler doesn't understand that the variable is initialized in either the try or the catch block. Compiler complains because local variables should be declared and initialized at the same time but you have just declared it. If you use it in either block (try, catch, finally) without initialization compiler complain about it. Try it:

    int i;
    try {
        System.out.println(i);
        //i = 0;
    }
    catch (Exception e) {
        System.out.println(i);
        //i = 2;
    }
    finally {
        System.out.println(i);
    }