Java method contains another method throws exception - java

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.

Related

Java: testing for the throwing of checked exceptions

I'm trying to figure out a way to build a method that will test whether a checked exception has indeed been thrown. As I was building the following minimal working example (CustomThrowablexxx are all custom types declared on their own files for readability):
package demos.exceptions;
public class TestExceptions {
// This method will check whether the provided method throws exceptions
// of the type provided.
private static boolean throwsParticularThrowable(Runnable method,
Class<Throwable> cls){
try {
method.run();
} catch(Throwable t){
if(t.getClass().equals(cls))
return true;
}
return false;
}
private static void methodOne() throws CustomThrowableOne {
throw new CustomThrowableOne("methodOne() throws");
}
private static void methodTwo() throws CustomThrowableTwo {
throw new CustomThrowableTwo("methodTwo() throws");
}
private static void methodThree() throws CustomThrowableThree {
throw new CustomThrowableThree("methodThree() throws");
}
public static void main(String[] args){
if(!throwsParticularThrowable(TestExceptions::methodOne,
CustomThrowableOne.class))
System.out.println("Nope!");
}
}
I unfortunately noticed that the access to TestExceptions::methodOne was not safe, because the compiler complained that I'm not checking for the throwing of methodOne, which I guess makes sense.
Is there any way I can automate this instead of copying and pasting the code inside throwsParticularThrowable every time?
I don't know what you are looking for but it's easier to test if exceptions are thrown using JUnit ExpectedException
https://junit.org/junit4/javadoc/4.12/org/junit/rules/ExpectedException.html

Java method signature throwing same exception (via generics) twice

Case simplified:
Legacy code. 3 exceptions X,Y and ZException. Class A has method public C fetch(...) throws X and YException and class B has public C fetch(...) throws ZException. The method implementation is almost the same, so I was wondering could I refactor it to some helper class. Method signatures cannot be changed. I came up with the following helper class
public class Common<T extends Exception, V extends Exception>{
public static interface ExceptionSupplier<T extends Exception> {
public T create();
}
private ExceptionSupplier<T> es;
private ExceptionSupplier<V> es2;
public Common(ExceptionSupplier<T> es, ExceptionSupplier<V> es2) {
this.es = es;
this.es2 = es2;
}
public void method() throws T, V {
//example that would could throw both T and V
if (Math.random() < 0.5) {
throw es.create();
} else {
throw es2.create();
}
}
}
Then I can create instance of that Common class in A and B e.g.
helper = new CommonThrower<ZException, ZException>(zSupplier, zSupplier);
helper = new CommonThrower<XException, YException>(xSupplier, ySupplier)
and call helper.fetch(...) and it shows (in eclipse) beging throw correct types. However it will (as somewhat expected) throwing ZException twice.
My question is there any problem having a method signature throws SomeException, SomeException (i.e. declaring the same exception again)? The code compiles and runs fine.
... throws IOException, IOException { ... .
Redundancy is just confusing, but runs fine.
A more common example of redundancy is something like
throws StreamCorruptedException, IOException {
In this case StreamCorruptedException is an IOException so it is not needed, but might be included to make it consistent with the Javadoc which might give more details for this exception.

Widening exception of overridden method in Java

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.

throws vs Java Bytecode

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;
}

Java : Exception declaration while method overidding

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..

Categories

Resources