throws vs Java Bytecode - java

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

Related

Why do Throwable instances get their stacktrace filled in during instantiation rather than right before throwing?

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?

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.

High Level Overview Of Throwing Exceptions In Java

I am a little bit confused with exceptions in Java and when to use which particular style of implementation.
I used IllegalArgumentException as an example, but the main point I would like to address is when does one throw, extends or throw new exception?
Also as an additional point I have an assignment where I have to create a java class and the spec vaguely states that the constructor should throw an IllegalArgumentException so which one would be the best to use?
public class Test{
//when does one use this type of exception
public Test(String yourName) throws IllegalArgumentException{
//code implemented
}
//when does one use this type of exception
public Test(String yourName) extends IllegalArgumentException{
//code implemented
}
public Test(String yourName){
if(yourName.length() <= 0){
//why not use this type of exception instead
//and what happens when I use this type of exception
throw new IllegalArgumentException("Please Enter Your Name..!");
}
}
}
Thanks in advance.
When some Exception occurs, you have two ways of handling it: doing throws from the method or doing try-catch. The first one looks like this:
public class MyClass {
public void myMethod() throws IllegalArgumentException {
someOtherMethod();
}
}
In this case you know that someOtherMethod() can throw an exception and you don't want to handle it - you just pass it further. After that, the invoker of myMethod() should take care of the Exception.
But the second way is when you handle it by yourself:
public void myMethod() {
try {
someOtherMethod();
} catch (Exception e) {
System.out.println("You've got an exception!");
}
}
About throwing exceptions manually - you may suppose that you do it in someOtherMethod(). When you do throw new IllegalArgumentException("Please Enter Your Name..!"); the program stops with a message about this exception (unless you handle it in a try-catch way).
And at last, you extend some exception, when you create your own Exception class:
class MyException extends IllegalArgumentException {
...
}
In this case you may do throw new MyException(); in your code.
I'd advise you to read more about exceptions in Java to understand what is going on. You may start with this lesson.
To ensure that you don't end up creating exceptions which already have equivalent in the standard library, I normally have a peek at the documentation before creating new exceptions. Also, it's very easy to go crazy with really big exception hierarchies if you are not careful. Don't create new exceptions just because you think you need to throw one somehow; create one because a code somewhere down the call stack would be doing something useful/different with that exception.
public Test(String yourName) throws IllegalArgumentException
You normally never specify runtime exception in the throws clause though it might be helpful if you need this information to be part of the public API.
public Test(String yourName) extends IllegalArgumentException
This doesn't look right and isn't valid Java.
I would only create a new exception type when you need to. You need a new type when you expect the caller to have catch clause for your new exception.
you can create new exceptions just to be more descriptive but that is what I use the message for.

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

Java method contains another method throws exception

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.

Categories

Resources