Using the Throwable class - java

I know that each java class should extend the Throwable class so that exceptions can be handled. Is this done by:
public class Test extends Throwable
or
public class Test throws Throwable?

Primitive types, or object whose class doesn’t extend Throwable cannot be thrown as exceptions.
Interpretation:
throw 3;
doesn't work because 3 is a primitive type.
throw new String();
doesn't work because String doesn't extend Throwable.
throw new RuntimeException();
works because RuntimeException is a subclass of Throwable.

I know that each java class should extend the Throwable class so that exceptions can be handled.
No, someone lied to you.
To handle exceptions, you need to keep in mind two things:
If it's a checked exception, then the class will refuse to compile if there is not a try...catch block wrapping the dodgy code, or if you don't declare the exception to be thrown.
try {
File f = new File("Foo.txt");
} catch (FileNotFoundException f) {
System.out.println("File doesn't exist!");
}
or:
public void doDodgyStuffWithFile throws FileNotFoundException { }
If it is an unchecked exception, then you will not get a compile-time failure for not catching the dodgy code, but you may get runtime exceptions from it.
String input = scanner.nextLine();
System.out.println(Integer.parseInt(input));
If you are throwing or catching the exception, be as specific as possible. Do not give into the temptation to throw/catch Exception, and never catch a Throwable.

When a class extends a Throwable, the class is a sub-class of Throwable and you can throw this class as a Throwable anywhere in you code.
class MyCoolThrowable extends Throwable{
try {
//... some error ...
} catch (MyCoolThroable t) {
//... handle the throwable
}
}
You add throws Throwable to a constructor or method so that the code that calls your constructor/method will be forced to use try-catch
void mySweetMethod() throws Throwable {
//...
}
try {
mySweetMethod();
} catch(Throwable t) {
//... handle it here
}
I think this clarified what you have read:)

Related

Why does this compile? Overriding method not a subclass of exception

I have a hard time to understand why the following code compiles, while it is not a subclass of exception:
class Test
{
public void run() throws IOException
{
System.out.println("Test");
}
}
class SubTest extends Test
{
//not a subclass of IOException, still compiles
public void run() throws RuntimeException
{
System.out.println("Test from sub");
}
}
class Sub2Test extends Test
{
//not a subclass of IOException, does not compile
public void run() throws Exception
{
System.out.println("Test from sub");
}
}
I understand RuntimeException is an unchecked exception, but I thought the rule was that it must be a subclass of the parent exception?
Imagine there is a caller which calls Test#run. In the declaration of Test#run, it says it might throw IOException, so the caller knows it can catch and handle it:
Test test = // it could be instance of SubTest of Sub2Test
try {
test.run();
} catch (IOException e) {
}
Then it's ok if SubTest does not throw IOException, the caller will not miss anything.
But if you throw some checked Exception like Sub2Test, since the caller does not know it until runtime, the called is not able to catch and handle it. So it should not be compiled.
"I understand RuntimeException is an unchecked exception, but I thought the rule was that it must be a subclass of the parent exception?"
That is the general rule, as specified in the JLS in section §11.2. Compile-Time Checking of Exceptions, which states (emphasis mine)
The throws clause of an overriding method may not specify that this method will result in throwing any checked exception which the overridden method is not permitted, by its throws clause, to throw (§8.4.8.3).
But that only applies to checked exceptions, and it also explicitly states that
The unchecked exception classes (§11.1.1) are exempted from compile-time checking.
So the compiler is going to ignore the fact that RuntimeException isn't a subclass of IOException.

throwing Generic Exception in java

I have another challenging question from javaDeathMatch game;
In the code below we are asked what kind of problem the code below has.
please correct me if I am wrong;
compilation error : None; At compile time the erasure of type parameter has not still occurred and the dynamic binding has not been taken place, so the parameter passed to the method which is of type SQLException is thought of as Exception in the method 'pleaseThrow' and it(i mean Exception not SQLException) is cast to Runtime Exception in the method with no error. The only error is that we don't have a proper catch clause to catch the exception.
public class Exption<T extends Exception> {
public static void main(String[] args) {
try {
new Exption<RuntimeException>().pleaseThrow(new SQLException());
}catch (final SQLException ex){
ex.printStackTrace();
}
}
private void pleaseThrow(final Exception t) throws T{
throw (T)t;
}
}
if we replace the catch clause with this:
catch(final RuntimeException e){
e.printStackTrace();
System.err.println("caught");
}
the exception will be caught but the System.err.println("caught") will never be printed!!! What is the problem????
This is due to type erasure. In java after compilation, every generic information is lost (there is something left, which is not relevant to this though). That means that during compilation, the generic variable T is equal to RuntimeException. So your pleaseThrow code looks like this:
private void pleaseThrow(final Exception t) throws RuntimeException{
throw (RuntimeException)t;
}
After compilation though, every generic parameter is erased to the base type. In your case, to Exception. Which leaves you with a method signature like this:
private void pleaseThrow(final Exception t) throws Exception{
throw (Exception)t;
}
Which finally is clear, why your catch block is never reached. You're trying to catch RuntimeExceptions but what you're actually throwing is a checked exception. Which then propagates upwards and is finally caught by the JVM.
Additional reading: Oracle Tutorial on type erasure
This code will fail to compile, because SQLException is a checked exception, and to catch a checked exception, it must be declared to be thrown by something inside of the try block. Here it is failing to compile on Ideone, for example, with the following message:
Main.java:7: error: exception SQLException is never thrown in body of corresponding try statement
}catch (final SQLException ex){
^
Note: Main.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
If you change the catch block so it catches RuntimeException, then the code will compile, but the exception will not be caught, because SQLException is not a subclass of RuntimeException.
There's a discussion of how the pleaseThrow method works here. That idiom is usually called "sneaky throws", and it lets the caller throw a checked exception as if it was an unchecked exception. For the difference between checked and unchecked exceptions, see the official tutorial or this Q&A and StackOverflow.
Let us take the first version of your code :
public class Exption<T extends Exception> {
public static void main(String[] args) {
try {
new Exption<RuntimeException>().pleaseThrow(new SQLException());
}catch (final SQLException ex){ // This is compilation error
ex.printStackTrace();
}
}
private void pleaseThrow(final Exception t) throws T{
throw (T)t;
}
}
How is compiler able to detect the error ?
It is not because of throw (T)t;. Infact , if you type cast to a type parameter , compiler ignores it and leaves it to JVM.
Then how does compiler able to generate error ?
It is because of this :
private void pleaseThrow(final Exception t) throws T
Notice the throws T . When you say new Exption<RuntimeException>() , compiler does not create any object. But it infers T during compilation. It comes under it powers.
Now , let us understand the whole picture of why error gets generated.
Compiler from private void pleaseThrow(final Exception t) throws T{ knows that you will throw RuntimeException.
According to rule of type casting , compiler checks both types if one is parent of other. If yes , it passes the code to JVM . Only JVM will then further check if one object can actually be type casted to other.
Similarly, compiler checks for throws and catch block if any is compatible or not. If more than one is compatible, it leaves the decision to JVM. Compiler checks for many other things too but let us focus on the main track.
In your example, One type is SqlException and other is RuntimeException. None is parent of other. Hence, compiler shows error.
Let us see few examples to clear it :
public class Exption<T extends Exception> {
public static void main(String[] args) {
try {
new Exption<RuntimeException>().pleaseThrow(new IllegalArgumentException());
}catch (final ClassCastException ex){
ex.printStackTrace();
System.out.println("done");
}
}
private void pleaseThrow(final Exception t) throws T{
throw (T)t;
}
}
In this example, Catch clause won't be called , however code compiles fine.
Since ClassCastException is a RuntimeException , Compiler compiles the code fine. RuntimeException is parent to ClassCastException.
But when compiler hands over code to JVM, JVM knows that exception object is of type IllegalArgumentException and hence will settle for a catch clause of IllegalArgumentException or it's super type. Here we have nothing like that. Hence, Catch clause won't be called as there is no match.
Take another example :
public class Exption<T extends Exception> {
public static void main(String[] args) {
try {
new Exption<RuntimeException>().pleaseThrow(new IllegalArgumentException());
}catch (final RuntimeException ex){
ex.printStackTrace();
System.out.println("done");
}
}
private void pleaseThrow(final Exception t) throws T{
throw (T)t;
}
}
This runs fine and catch block is called. JVM knows object type will be IllegalArgumentException and RuntimeException is super class , hence , it matches due to super class able to refer child class object.
Now, let us come back to your code.
You have only written only one catch block consisting of SqlException which is a checked exception and hence cannot be thrown from pleaseThrow() as it throws RuntimeException according to compiler.
So, this error gets generated :
Error:(9, 10) java: exception java.sql.SQLException is never thrown in body of corresponding try statement
As you know it is illegal in Java to have a catch block catching a checked expression never thrown.
Now , let us come to version 2 of your code :
public class Exption<T extends Exception> {
public static void main(String[] args) {
try {
new Exption<RuntimeException>().pleaseThrow(new SQLException());
}catch(final RuntimeException e){
e.printStackTrace();
System.err.println("caught");
}
}
private void pleaseThrow(final Exception t) throws T{
throw (T)t;
}
}
Now, things make sense as in catch block you have written RuntimeException.
Compiler sees that method throws RuntimeException and in catch block too we have runtime exception.
Now, let us look more closely. Compiler easily compiles this code and send it to JVM. But before that it does the type erasure.
Let us look what would type erasure would have done to our code :
[In actual code given to JVM is byte level code. The below example is to show what type erasure does to the code. Note that below code won't run properly in compiler if you try to compile as this code is after type erasure and few details have been lost which compiler needs. JVM however can run the equivalent byte code of this.]
public class Exption {
public static void main(String[] args) {
try {
new Exption().pleaseThrow(new SQLException());
}catch(final RuntimeException e){
e.printStackTrace();
System.err.println("caught");
}
}
private void pleaseThrow(final Exception t) throws java.lang.Exception {
throw (java.lang.Exception) t;
}
}
To understand how this code was reduced to , you need to read about type erasure. But trust me till here for time being.
Now, this code is very interesting piece of code.
On this code JVM directly operates. If you see JVM knows it method throws an Object of type SqlException type casted to Exception. It tries to find a match in catch blocks but no match. RunTimeException is not a super class of SqlException. Hence, no catch block is called.
Let us modify the code to understand it more.
public class Exption<T extends Exception> {
public static void main(String[] args) {
try {
new Exption<RuntimeException>().pleaseThrow(new SQLException());
}catch(final RuntimeException e){
e.printStackTrace();
System.err.println("caught");
}catch(Exception r){
System.out.println("done");
}
}
private void pleaseThrow(final Exception t) throws T{
throw (T)t;
}
}
This will output "done".

Netbeans not forcing me to try catch when method throws an exception

I'm using Netbeans 8 IDE and I just came to this odd situation. Let's say I've a method in a class that throws and Exception and when I call that method Netbeans does not enforce the try catch. Sometimes an Exception may occur and it is not catch.
Why isn't Netbeans enforcing the try catch method?
Here's an example:
public class MyMethodClass {
public MyMethodClass() {}
public void someMethod() throws NullPointerException {
// do something
if(something == null) {
throw new NullPointerException();
}
// do something else
}
}
public class MyClass {
public MyClass() {
MyMethodClass mmc = new MyMethodClass();
// Here Netbeans does not force me to use a try catch, why?
mmc.someMethod();
}
}
NullPointerException is an unchecked exception, which means that you don't always need to catch it. Unchecked exceptions are those which extend RuntimeException or Error. The main purpose of these is for cases where there usually is no recovery; methods aren't required to declare unchecked exceptions either. This is perfectly valid:
public void throwNPE() {
throw new NullPointerException();
}
Here is one of Oracle's statements on checked vs unchecked exceptions.
NullPointerException is an unchecked exception (since it's a subclass of RuntimeException). You don't have to catch unchecked exceptions for the code to compile.
RuntimeException and its subclasses are unchecked exceptions. Unchecked exceptions do not need to be declared in a method or constructor's throws clause if they can be thrown by the execution of the method or constructor and propagate outside the method or constructor boundary
Because NullPointerException is an unchecked exception.

Java throw exception at class method

I have question on Java throw exception at class method definition:
public void someMethod () throws SomeException {
try{
...
}catch (SomeException e ){
....
}
}
When we declare throw SomeException at the method declaration, do we still have to try/catch in the body or, can we just use throw new SomeException like this:
public void someMethod () throws SomeException {
// do something
throw new SomeException() ;
}
what is the correct way to throw exception when we have throw Exception at the method declaration.
No, you do not need to catch the exception that you throw as long as you're not changing it or selectively throwing it only in some situations when the exception occurs. So this is often perfectly fine:
public void someMethod () throws SomeException {
// do something
throw new SomeException() ;
}
Although it's often good to give your SomeException class a constructor that takes a String parameter, and then pass that String to the super constructor to allow your exception to be able to pass more information through.
Your prototype public void someMethod () throws SomeException is mandating that someMethod will only throw exceptions of type SomeException. (Or any exception classes derived from SomeException).
Therefore you do not need to catch that particular exception in your function, but you will need to catch all others.

java : how to handle the design when template methods throw exception when overrided method not throw

when coding. try to solve the puzzle:
how to design the class/methods when InputStreamDigestComputor throw IOException?
It seems we can't use this degisn structure due to the template method throw exception but overrided method not throw it. but if change the overrided method to throw it, will cause other subclass both throw it.
So can any good suggestion for this case?
abstract class DigestComputor{
String compute(DigestAlgorithm algorithm){
MessageDigest instance;
try {
instance = MessageDigest.getInstance(algorithm.toString());
updateMessageDigest(instance);
return hex(instance.digest());
} catch (NoSuchAlgorithmException e) {
LOG.error(e.getMessage(), e);
throw new UnsupportedOperationException(e.getMessage(), e);
}
}
abstract void updateMessageDigest(MessageDigest instance);
}
class ByteBufferDigestComputor extends DigestComputor{
private final ByteBuffer byteBuffer;
public ByteBufferDigestComputor(ByteBuffer byteBuffer) {
super();
this.byteBuffer = byteBuffer;
}
#Override
void updateMessageDigest(MessageDigest instance) {
instance.update(byteBuffer);
}
}
class InputStreamDigestComputor extends DigestComputor{
// this place has error. due to exception. if I change the overrided method to throw it. evey caller will handle the exception. but
#Override
void updateMessageDigest(MessageDigest instance) {
throw new IOException();
}
}
In this case, your super class is not meant to throw an exception.
This is a case where your subclass is thus throwing an exception which is not expected by the overlying software architecture. Thus you can :
update all subclasses to throw exceptions.
wrap the entire Digestor class framework in a new class system.
(simplest) maintain the current code and simply wrap any exceptions you wish to throw in a RuntimeException.
RuntimeExceptions are the idiomatic way to throw exceptions in java which are not checked by the compiler or by method signatures, which occur somewhat unexpectedly.
Your requirements are schizophrenic.
You've got to decide whether the DigestComputor.updateMessageDigest method can, or can not throw IOException. If you want that to be possible, then you must add it to the signature in the base class. That is the only way to force the caller to do something about an IOException. But the downside is that you also force callers of the other subclasses to handle the IOException ... which won't occur.
You cannot create a method override that throws checked exceptions that the overridden method does not. That would break subtype substitutability, and Java doesn't allow it.
It it like a fork in the road. You have to decide to go one way or the other. You can't go both ways at the same time.
However there is a compromise (sort of):
public abstract class Base {
public abstract void method() throws IOException;
}
public class A extends Base {
public void method() throws IOException {
//
}
}
public class B extends Base {
public void method() { // Doesn't throw!!!
//
}
}
Now, if the caller knows that it has an instance of B it can do something like this:
Base base = ...
B b = (B) base;
b.method(); // No need to catch or propagate IOException
(IIRC, the ability to do this ... i.e. to reduce the exceptions thrown in an overriding method ... was added in Java 1.5.)
As someone else suggested, the simplest thing to do would be to simple wrap the real exception in a runtime exception. As a result, you don't have to declare the exception in your throws clause. If you're ambitious enough you can make your own subclass of RuntimeException and catch it at a higher level (this is what hibernate does, it catches all SQLExceptions thrown and wraps them in some subclass of DataAccessException which is a runtime exception).

Categories