The question is about the result of the below code. The answer is compilation error. However I really do not understand why we can't have constructor in try/catch block. I will put the the code below:
public class Test {
try {
public Test() {
System.out.println("GeeksforGeeks");
throw new Exception();
}
}
catch(Exception e) {
System.out.println("GFG");
}
public static void main(String [] args) {
Test test= new Test();
}
}
Because the assignments are statements and statements are allowed only inside blocks of code(methods, constructors, static initializers, etc.)
here's the clean code
public class Test {
public Test()throws Exception {
System.out.println("GeeksforGeeks");
throw new Exception();
}
public static void main(String [] args) {
try {
Test test= new Test();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Because a constructor is a declaration, not a statement.
Your constructor can be called by other code, but merely declaring it does not execute it; that’s what new Test() does. Nothing is executed merely by declaring the constructor, so there is nothing that can throw an exception. Thus, there is nothing to catch.
In more general syntax terms, statements which don’t evaluate to a value can only exist in constructors, methods, and initialization blocks.
You can, however, do this:
public static void main(String[] args) {
try {
Test test = new Test();
} catch (Exception e) {
System.out.println(e);
}
}
new Test() actually executes the constructor, which is why it may throw an exception and thus you can legally attempt to catch any exception it may throw. Syntactically, all of the above code is inside a method (the main method), which is allowed.
Related
What does <init> signify in a Java exception?
For example:
BlahBlahException...
at java.io.FileInputStream.<init>(FileInputStream.java:20)
That the exception is thrown in the construction of the object, there are two options:
in the constructor
while initializing variables
Check out this demo I wrote: http://ideone.com/Mm5w5
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
try
{ new Test(); } catch (Exception e) { e.printStackTrace(); }
try
{ new Test2(); } catch (Exception e) { e.printStackTrace(); }
try
{ new Test3(); } catch (Exception e) { e.printStackTrace(); }
}
static class Test
{
Object obj = getObject();
Object getObject()
{ throw new RuntimeException("getObject"); }
}
static class Test2
{
Test2()
{
throw new RuntimeException("constructor");
}
}
static class Test3
{
Object obj1 = null;
String str = obj1.toString();
}
}
Produces:
java.lang.RuntimeException: getObject
at Main$Test.getObject(Main.java:24)
at Main$Test.<init>(Main.java:22)
at Main.main(Main.java:9)
java.lang.RuntimeException: constructor
at Main$Test2.<init>(Main.java:31)
at Main.main(Main.java:12)
java.lang.NullPointerException
at Main$Test3.<init>(Main.java:38)
at Main.main(Main.java:15)
<init>
is called
Instance Initialization method
which is created by your java compiler from the constructor you have defined. Though it is not valid method definition, your JVM expects this and anything that you put in the constructor will be executed in method. So when you an exception with from , you can be sure that it is from the constructor of the executed java class. Read more about this on Bill venner's design technique articles on Object Initialization.
I need methodA2 also gets executed even though there is an exception by methodA1(). Here I have added only two methods as methodA1() and methodA2(). Let's say there are many methods. In that case also, the solution should be able to applicable.
class A {
String methodA1() throws ExceptionE {
// do something
}
String methodA2() throws ExceptionE {
// do something
}
}
class C extends A {
String methodC() throws ExceptionE2 {
try {
methodA1();
methodA2();
} catch (ExceptionE e) {
throw new ExceptionE2();
}
}
}
Please note that there can be many methods invoked with methodA1, methodA2. In that case having multiple try, catch, finally will look ugly.. So are there any other methods to do that?
I need to store error information in a log file. In methodA1(), methodA2() ... information in each tag is get validated. what I want is having all the error information in log file. Once exception throws it will generate log file. So I will miss validation information from other tags. So we can't go for finally approach.
You can use a loop with Java 8 lambdas:
interface RunnableE {
void run() throws Exception;
}
class Example {
public static void main(String[] args) {
List<RunnableE> methods = Arrays.asList(
() -> methodA1(),
() -> methodA2(),
() -> methodA3()
);
for (RunnableE method : methods) {
try {
method.run();
} catch (Exception e) {
// log the exception
}
}
}
private static void methodA1() throws Exception {
System.out.println("A1");
}
private static void methodA2() throws Exception {
System.out.println("A2");
}
private static void methodA3() throws Exception {
System.out.println("A3");
}
}
Please note that the interface is needed only when methods throw checked exception. If they were throwing only runtime exceptions, you could use java.lang.Runnable instead.
No other way. If each method can throw exception, but you want to continue execution of remaining methods anyway, then each method call must be in its own try-catch block.
Example:
List<Exception> exceptions = new ArrayList<>();
try {
methodA1();
} catch (Exception e) {
exceptions.add(e);
}
try {
methodA2();
} catch (Exception e) {
exceptions.add(e);
}
try {
methodA3();
} catch (Exception e) {
exceptions.add(e);
}
if (! exceptions.isEmpty()) {
if (exceptions.size() == 1)
throw exceptions.get(0);
throw new CompoundException(exceptions);
}
You will of course have to implement the CompoundException yourself.
I'm making a game and my try and catch blocks work inside the methods, but one of the criteria for my assignment is to place the main method into a try catch block as well. But whenever I wrap my main method in a try{ } block, it gives me a compile error: Illegal start of type. I've looked this up and I've concluded I need to place the try block into its own method, but when I do this I get an Illegal start of expression. How exactly do I place my main method into a try catch block?
Main method:
public static void main(String[] args){
Board board = new Board();
board.display();
board.validate();
}
When I tried wrapping it in a try catch block (Illegal start type)
try{
public static void main(String[] args){
Board board = new Board();
board.display();
board.validate();
}
}
And when I tried to place it inside a method (Illegal start of expression)
public void tryCatch(){
try{
public static void main(String[] args){
Board board = new Board();
board.display();
board.validate();
}
}
}
You don't, you wrap the contents of your main method in the try-catch or have the main method re-throw the resulting exception
public static void main(String[] args){
try {
Board board = new Board();
board.display();
board.validate();
} catch (... exp) {
exp.printStackTrace();
}
}
Take a closer look at Catching and Handling Exceptions for more details
public static void main(String[] args) throws Exception {
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Caught Exception " + e);
}
});
throw new Exception("a serious problem occured");
}
and here is the output
Caught Exception java.lang.Exception: a serious problem occured
I ran into a strange problem with try catch which got me doubting about my own realization of exception handling fundamentals. As per the basic syntax
try{
code to be checked
}
catch(Exception e){}
finally{}
However the code below gives me a null pointer exception which I believe should have been caught.
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
try{
for(Model m: Null Collection coming from DB)
System.out.println("Inner Block");
System.out.println("Outer Block");
}catch(Exception e){}
}
}
The following snippet prints "An exception!"
List<String> strings = null;
try {
for (String s : strings) {
System.out.println(s);
}
} catch (Exception e) {
System.out.println("An exception!");
}
And as others have pointed out, and you stated yourself, Runtime exceptions are caugth by Exception catches
Have you tried recompiling all your code from scratch? In my team (250.000 lines codebase) using eclipse we sometimes have trouble with bad compiles that can give unexplainable problemes like this. We usually solve them by a complete recompile.
Are you sure about your issue? I believe there's some clean-up code in your catch which hasn't been initialized yet - hence the exception. Would help if you post your actual code.
The following works as expected:
import java.util.List;
public class Main {
public static void main(String[] args) {
List i=null;
try{
for(Object o: i) {
System.out.println("Inner Block");
}
System.out.println("Outer Block");
}catch(Exception e){}
}
}
Understanding the Try Catch block behavior?
The main reason to use try-catch block is to handle something will goes wrong with your code or something you are unexpected for the normal case and something will throw an exception somehow and to handle it in catch block, and the finally block is used almost to close any opened stream and it will run every time in the code even if the try or catch returned any value (except for system termination).
In your code it seems that there is something you get it from database which is null or not initialized yet or it is already returned from database of null value, Now you cannot use null object if it's not initialized already! you have to insure if it's null or not then use it like this:
class Ideone {
public static void main(String[] args) throws java.lang.Exception {
try {
if(Null Collection coming from DB != null){
for(Model m: Null Collection coming from DB)
System.out.println("Inner Block");
}
System.out.println("Outer Block");
} catch (Exception e) {}
}
}
The NullPointerException is extends RuntimeException and it's thrown when you try to use a null object.
i has not been initialized,
public class Ideone{
public static void main (String[] args) throws java.lang.Exception
{
int i = 0;
try{
if(i<2)
System.out.println("Inner Block");
System.out.println("Outer Block");
}catch(Exception e){}
}
}
Cannot reproduce.
I tried this
public static void main (String[] args) throws java.lang.Exception
{
Collection c = null ;
try{
for(Object i:c)
System.out.println("Inner Block");
System.out.println("Outer Block");
}catch(Exception e){}
}
It works well.
So I have a bit of situation here with my design and was wondering whether I could
get some feedback.
public class Class1 {
public void eatFish(){}
}
public class Class2 {
public void eatBacon(){
// some nasty code here to cause an exception
}
}
public class Class3 {
public void eatFruit(){}
}
public InvokeAllClasses() {
public static void main(String[] args) {
Class1 c1 = new Class1();
Class2 c2 = new Class2();
Class3 c3 = new Class3();
c1.eatFish();
c2.eatBacon();
c3.eatFruit();
}
}
See the problem here in InvokeAllClasses is that, because c2.eatBacon();
blows up, c3.eatFish() would not be executed. Is there a way to still execute
c3 although c2 blew up?
Update
After thinking more about, I guess I could wrap each call in a try...catch block but that is just messy.
Put the try...catch in the method defintion:
public void eatBacon(){
try{
// some nasty code here to cause an exception
} catch(Exception e){
//do something
}
}
This won't look as bad as putting it when you call the method. If you know where exactly in the code the exception could be happening, then only surround those statements.
You could handle the exceptions within the methods themselves so they aren't thrown back up to the calling method, but other than try/catch/finally blocks, there isn't a good practice way to ignore exceptions.
Unless you are sure that you will never have to handle any exceptions thrown by those methods, it might be better to avoid swallowing all of them at the source.
It's been a while since I wrote Java code and I could not try and compile it, but the idea is to create an object which has the responsability to execute tasks and swallow any exceptions.
It may look like:
public class SilentExecutor {
List<Runnable> tasks;
public SilentExecutor(List<Runnable) tasks) {
this.tasks = tasks == null? new List<Runnable>() : tasks;
}
public void execute() {
for (Runnable task : this.tasks) silentlyExecute(task);
}
private void silentlyExecute(Runnable task) {
try { task.run(); }
catch (Exception e) {}
}
}
Then your code could be something like:
new SilentExecutor(Arrays.asList(
() -> { c1.eatFish(); },
() -> { c2.eatBacon(); },
() - > { c3.eatFruit(); }
)).execute();
Why not just catch the exception and move on? I honestly don't think it will be messy.
Make your method to throw an exception.
public InvokeAllClasses() throws Exception {
public static void main(String[] args) {
Class1 c1 = new Class1();
Class2 c2 = new Class2();
Class3 c3 = new Class3();
try{
c1.eatFish();
}catch(Exception e){System.out.println("Oh noes! There was something wrong!!!")}
finally{
c2.eatBacon();
c3.eatFruit();
}
}
As you can see. The "finally" statement will force your code to perform no matter if the statement inside the try fails or throws an exception.
There are two approaches you could take. The first option is to ignore the exceptions completely.
try {
c1.eatFish();
} catch(Exception e) {//Ignore}
try {
c2.eatBacon();
} catch(Exception e) {//Ignore}
try {
c3.eatFruit();
} catch(Exception e) {//Ignore}
If you want the exception to be thrown in the end, you can put the result into a variable and then throw it at the end or use the finally clause.
try {
c1.eatFish();
finally {
try {
c2.eatBacon();
} finally {
c3.eatFruit();
}
}
If you are looking for something more readable, you could wrap the method calls.
public static void main(String[] args) {
Class1 c1 = new Class1();
Class2 c2 = new Class2();
Class3 c3 = new Class3();
callEatFishIgnoringException(c1);
callEatBaconIgnoringException(c2);
callEatFruitIgnoringException(c3);
}
private static void callEatFishIgnoringException(Class1 c1) {
try {c1.eatFish()} catch (Exception e) {//Ignore}
}
private static void callEatBaconIgnoringException(Class2 c2) {
try {c2.eatBacon()} catch (Exception e) {//Ignore}
}
private static void callEatFruitIgnoringException(Class3 c3) {
try {c3.eatFruit()} catch (Exception e) {//Ignore}
}