class MyException extends Exception { }
class Tire {
void doStuff() { } // #4
}
public class Retread extends Tire {
public static void main(String[] args) {
new Retread().doStuff();
}
// insert code here
System.out.println(7/0);
}
And given the following four code fragments:
void doStuff() {
void doStuff() throws MyException {
void doStuff() throws RuntimeException {
void doStuff() throws ArithmeticException {
When fragments 1 - 4 are added, independently, at line 10, which are true? (Choose all that apply.)
A. None will compile
B. They will all compile
C. Some, but not all, will compile
D. All of those that compile will throw an exception at runtime
E. None of those that compile will throw an exception at runtime
F. Only some of those that compile will throw an exception at runtime
Answer: C and D are correct. An overriding method cannot throw checked exceptions that are broader than those thrown by the overridden method. However an overriding method can throw RuntimeExceptions not thrown by the overridden method. A, B, E,and Fare incorrect based on the above. (Objective 2.4)
I dont get what the BoldItalic marking is saying in this context. The overriding method(#4) doesnt throw any exception so how do we know if the one (in this case MyException) we add to the overridden method ( option 2) is broader than the overriding method. How does Arithmetic exception runs with no error. How is it not broader than the dont-know-which-exception in the overriding method.
You override method void doStuff() { } which throws no exception with one of the options. So let's look at them, one by one:
void doStuff() { .. }
This one is okay, it throws no Exception like the base method.
void doStuff() throws MyException { .. }
This one won't compile. MyException is a checked exception because it extends Exception and the base method doesn't declare any checked exceptions at all.
void doStuff() throws RuntimeException { ... }
This will work, because RuntimeException is an unchecked exception.
void doStuff() throws ArithmeticException { ... }
This will work too, because ArithmeticException is a RuntimeException, so unchecked.
void doStuff() { }
is not throwing any checked exception .
so the overriding method should also not throw any checked exception,
although it can throw a runtime exception(which need not to be mentioned be declaration).
If the overridden method doesn't throw a checked exception, overriding method cannot throw, too. Throwing checked exceptions means nothing for compile time. You can throw any subclass of Runtime Exception without saying that this methods throws blah blah.
Runtime exceptions are generally bugs and development mistakes, such as nullpointerexception and arithmeticexception. You need to check those kind of pointers/values before sending them to a method. Otherwise, the program crashes.
Hovewer, you have nothing to do with checked exceptions except try/catch. They can have many causes such as connection error, file system error, operating system permissions, etc..
Related
I'm not sure if this question was asked before, but I've been always wondering why every instance of Throwable, unless the fillInStackTrace method is overridden/suppressed, fills its stacktrace in the constructor while being instantiated by default.
Consider the following code:
final class ThrowableTest {
private ThrowableTest() {}
public static void main(final String... args) throws Throwable { throw go(); }
private static Throwable go() { return goDeep(); }
private static Throwable goDeep() { return goDeeper(); }
private static Throwable goDeeper() { return goEvenDeeper(); }
private static Throwable goEvenDeeper() { return new Throwable(); }
}
Executing the code above would produce the following output:
Exception in thread "main" java.lang.Throwable
at ThrowableTest.goEvenDeeper(scratch.java:9)
at ThrowableTest.goDeeper(scratch.java:8)
at ThrowableTest.goDeep(scratch.java:7)
at ThrowableTest.go(scratch.java:6)
at ThrowableTest.main(scratch.java:5)
I would find the following hypothetical stacktrace more intuitive (assuming the fillInStackTrace method is not overridden and the Throwable constructor does not invoke it in such a "special" JRE):
Exception in thread "main" java.lang.Throwable
at ThrowableTest.main(scratch.java:5)
I'm wondering: why is the stacktrace filled in the constructor (in its simplest scenario) rather than at the exception throwing site using throw?
If I'm not mistaken, there are some scenarios when fillInStackTrace can be used to configure the exception to be (re)thrown, and the throw as described would re-write the stacktrace to the current one.
But if so, the throw statement (and the athrow instruction) might check if the stacktrace of the exception is set to null before filling it up on its own (assuming that throwing something other than an instance of Throwable is undefined as it's described in the specification).
What was the design choice behind it?
Assume we have two classes:
Class A:
import java.io.IOException;
public class A {
public void test() throws IOException{
System.out.println("test in A");
}
}
Class B:
import java.io.IOException;
public class B extends A {
#Override
public void test() throws Exception{
System.out.println("test in B");
}
}
This gives a compiler error, and I would like to know the reason for it. I can get the answer by myself, but this is not fully scientific, but partly logically.
I wrote a blog post in Azerbaijani. When I wrote the blog I was stuck in the loading process.
Please be careful in quotes:
I think that when the compiler reads the B class, it loads the method headers of A and method headers of B. And when you call test of A, the JVM calls the test of A, but as body calls test of B, and at that time we will have this method:
public void test() throws IOException{ // <-- Header of A
System.out.println("test in B"); // <-- Body of B
// Here I can throw wide Exception from IOException
// because here is the body of the test in B. The test
// method in B can throw Exception so the compiler
// doesn't approve of this version of the code.
}
Is the process really going on as what I wrote above?
Loading headers issue I was stuck exactly here.
How does the linking process work? I can't figure out background of
A a = new B(); // When the compiler converts this line into bytecode
// does it loads of method headers of A and method
// body's of B
a.test()
calls the test of the B class. I know logically, but I can't figure out at the compiler level, linking process.
Imaigine you have the following code:
A a = new B();
try {
a.test();
} catch (IOExceoption e) {
//do some specific handle for IOExceoption
}
Now imaigine what happens if b.test() throw an Exception which is NOT IOException? nobody will handle it, and that breaks java's checked exceptions mechanism.
The other way around however, is perfectly fine:
public class A {
public void test() throws Exception {
System.out.println("test in A");
}
}
public class B extends A {
#Override
public void test() throws IOException{
System.out.println("test in B");
}
}
A a = new B();
try {
a.test();
} catch (Exception e) {
//handle
}
Now, note that the catch handles a general Exception, including the specific IOException, and the code will compile perfectly.
The overidden method can throw anything which is an IOException your case. Or more generally, it can throw any exception that is a ParentException. So, you can throw FileNotFoundException since it is also an IOException.
Why?
Not adhereing to this rule breaks the primary contract between parent-child in inheritance.
Somewhere else in your code you can safely assume that the exception thrown from the call to test() will always be IOException irrespective of Which implementation of A threw it. If you were allowed to throw InterruptedException in your case, what exception should the caller catch?
The compiler doesn't load anything. It just marks the method as invoke virtual which means this method is overriden and supposed to be called at run-time based on the object type
From a bit different angle, you are basically not overriding existing method in super type.
Exceptions which are thrown are part of the method's signature.
When you declare your test method in class B with override annotation, you are in fact trying to override (or implement) method which does not exist in its parent A.
The throws list of a method obviously plays a role during compilation. Does it however have any impact whatsoever during runtime?
For instance, if I have a method without a throws list and use dark bytecode magic to summon and throw an IncrediblyCheckedException, would it throw it without question or would the runtime validator notice this and throw an error or something instead?
It has no effect on the runtime whatsoever. Case in point:
Thread.currentThread.stop(new Exception());
can be written anywhere and the line of code will throw the exception.
The above will throw the exception from native code, but here's another trick with a plain Java throw:
public static void main(String[] args) {
CurrentClass.<RuntimeException>sneakyThrow(new Exception());
}
#SuppressWarnings("unchecked")
private static <E extends Throwable> void sneakyThrow(Throwable t) throws E {
throw (E)t;
}
I have the below interface
public interface Interface1 {
Object Execute(String commandToExecute) throws Exception;
}
which then I 'm trying to mock so I can test the behaviour of the class that will call it:
Interface1 interfaceMocked = mock(Interface1.class);
when(interfaceMocked.Execute(anyString())).thenThrow(new Exception());
Interface2 objectToTest = new ClassOfInterface2(interfaceMocked);
retrievePrintersMetaData.Retrieve();
But the compiler tells me that there is an unhandled exception.
The definition of the Retrieve method is:
public List<SomeClass> Retrieve() {
try {
interface1Object.Execute("");
}
catch (Exception exception) {
return new ArrayList<SomeClass>();
}
}
The mockito documentation only shows uses of RuntimeException, and I have not seen anything on similar on StackOverflow.
I'm using Java 1.7u25 and mockito 1.9.5
Assuming your test method doesn't declare that it throws Exception, the compiler's absolutely right. This line:
when(interfaceMocked.Execute(anyString())).thenThrow(new Exception());
... calls Execute on an instance of Interface1. That can throw Exception, so you either need to catch it or declare that your method throws it.
I would personally recommend just declaring that the test method throws Exception. Nothing else will care about that declaration, and you really don't want to catch it.
You can use doAnswer method of Mockito to thrown checked exceptions, like this
Mockito.doAnswer(
invocation -> {
throw new Exception("It's not bad, it's good");
})
.when(interfaceMocked)
.Execute(org.mockito.ArgumentMatchers.anyString());
You shouldn't be having a problem if your method returns something and throws your error. Now if your method returns void you won't be able to throw an error.
Now the real thing is that you're not testing that your interface throws an exception, instead what you're testing what happens when an exception is thrown within this method.
public List<SomeClass> Retrieve() {
try {
interface1Object.Execute("");
}
catch (Exception exception) {
return handleException(exception);
}
}
protected List<SomeClass> handleException(Exception exception) {
return new ArrayList<SomeClass>();
}
Then you just call your handleException method and make sure it returns the correct thing. If you need to make sure that your interface is throwing an exception, then that is a different test for your interface class.
It might seem sucky that you are having to make a method for a single line but that's what happens sometimes if you want testable code.
Inside Method A, there is method B. Method B throws exception, but method A compiled even it does not catch exception or throws exception, could it be possible?
Method B is something like as below:
MethodB() throws SomeException{
if(Some)
doneSomething
return
else if(some)
donesomethingElse
return
throw SomeException
}
If the SomeException extends RuntimeException. Then you don't need to catch it even if the signature looks like that.
Also note that you can just remove the throws SomeException in that case. Read more here.
Yes, there are some unchecked exception, who might not be caught / rethrown.
Look at this tutorial - Unchecked Exceptions.
Even if SomeException is a checked exception, this can happen due to separate compilation.
Suppose you write a class:
public class B {
public static void foo() {
}
}
Then a class that calls it:
public class A {
public static void main(String[] args) {
B.foo();
}
}
Then say:
javac A.java
java A
All is fine. Now change B:
public class B {
public static void foo() throws java.io.IOException {
throw new java.io.IOException();
}
}
And this time just compile B before running:
javac B.java
java A
You get:
Exception in thread "main" java.io.IOException
at B.foo(B.java:4)
at A.main(A.java:4)
In the real world this happens when individual .jar files are updated after they've been modified by maintainers who don't understand the problems caused by adding more throws clauses.