The difference is that in the first case x is a compile time constant. i.e. the compiler knows that x will always have value 101, and by extension it knows that the if-condition will always be true and y will always be initialized to value -1. That's why it's legal to use y in the System.out.println() call: the compiler knows it was initialized to a value. In the other code sample x isn't a compile time constant and all the implications that held up in the first code sample don't. This leads the compiler to complain about the use of y, because it can't figure out whether or not it was initialized. At runtime, this is clearly the case, but the compiler just isn't smart enough to pick up on that.
@Thimal Deemantha: It's great that you want to help, and I'm glad to see you gave credit to the author for what you're quoting. However, if you understood what Jelle was telling you, then we can see that the code the OP provided doest not in fact produce a compiler error.
In fact, this is the same code as you provided in your thread, and just like the code you provided, it's missing something would produce a compile error. As it is, it compiles just fine.