Dude if take a look at this code, both are logically same, but this works fine.
Maybe so, but the compiler is not smart enough to know that. In the first case, it does know that the exception will be thrown, and hence, the code after the try-finally block is not reachable. In the second case, it is just an arithmetic expression, that is not checked for runtime errors during compile time.
If the complier knows then why isn't it complaining at compile time.If you analyze the following snippets,
Because the compiler doesn't know. It knows that it is a literal zero, and it knows that it will divide them, but there is no check at compile time to determine whether it may throw an exception at runtime. This may change in the future, as the compiler improves, but currently, it doesn't make such a check.