Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I use a try block around my super() call?

So, in Java, the first line of your constructor HAS to be a call to super... be it implicitly calling super(), or explicitly calling another constructor. What I want to know is, why can't I put a try block around that?

My specific case is that I have a mock class for a test. There is no default constructor, but I want one to make the tests simpler to read. I also want to wrap the exceptions thrown from the constructor into a RuntimeException.

So, what I want to do is effectively this:

public class MyClassMock extends MyClass {     public MyClassMock() {         try {             super(0);         } catch (Exception e) {             throw new RuntimeException(e);         }     }      // Mocked methods } 

But Java complains that super isn't the first statement.

My workaround:

public class MyClassMock extends MyClass {     public static MyClassMock construct() {         try {             return new MyClassMock();         } catch (Exception e) {             throw new RuntimeException(e);         }     }      public MyClassMock() throws Exception {         super(0);     }      // Mocked methods } 

Is this the best workaround? Why doesn't Java let me do the former?


My best guess as to the "why" is that Java doesn't want to let me have a constructed object in a potentially inconsistent state... however, in doing a mock, I don't care about that. It seems I should be able to do the above... or at least I know that the above is safe for my case... or seems as though it should be anyways.

I am overriding any methods I use from the tested class, so there is no risk that I am using uninitialized variables.

like image 388
Mike Stone Avatar asked Aug 07 '08 21:08

Mike Stone


People also ask

Can I execute multiple catch blocks without try will it give me compile time error?

You cannot have multiple try blocks with a single catch block. Each try block must be followed by catch or finally. Still if you try to have single catch block for multiple try blocks a compile time error is generated.

What happens if try catch block is not used?

3. If no exception occurs in try block then the catch blocks are completely ignored.

What is super in exception handling?

The super keyword in Java is a reference variable which is used to refer immediate parent class object. Whenever you create the instance of subclass, an instance of parent class is created implicitly which is referred by super reference variable.

Can we call a function in catch block?

You should call a method that handles that exception or takes some appropriate steps for exception. Now for your question, you can call any method that is accessible inside your method A() inside the catch block.


2 Answers

Unfortunately, compilers can't work on theoretical principles, and even though you may know that it is safe in your case, if they allowed it, it would have to be safe for all cases.

In other words, the compiler isn't stopping just you, it's stopping everyone, including all those that don't know that it is unsafe and needs special handling. There are probably other reasons for this as well, as all languages usually have ways to do unsafe things if one knows how to deal with them.

In C# .NET there are similar provisions, and the only way to declare a constructor that calls a base constructor is this:

public ClassName(...) : base(...) 

in doing so, the base constructor will be called before the body of the constructor, and you cannot change this order.

like image 125
Lasse V. Karlsen Avatar answered Oct 08 '22 11:10

Lasse V. Karlsen


It's done to prevent someone from creating a new SecurityManager object from untrusted code.

public class Evil : SecurityManager {   Evil()   {       try {          super();       } catch { Throwable t }       {       }    } } 
like image 39
Joshua Avatar answered Oct 08 '22 11:10

Joshua