Handling exceptions with interfaces and classes in java - java

So picture the following scenario. I have two sets of classes and interfaces. ClassA, ClassB, ClassAInterface, and ClassBInterface. ClassA uses ClassB in several of its methods. These methods from ClassB occasionally throw exceptions.
public class ClassA implements ClassAInterface {
public void example() {
ClassB test = new ClassB();
ClassB.exampleTest();
//more code using ClassB
}
}
public class ClassB implements ClassBInterface {
public void exampleTest() throws ExampleException() {
boolean tru = false;
if (tru) {
throw new ExampleException();
}
}
}
So the problem that I'm having is that I'm getting an Unhandled Exception type ExampleException() error in the ClassA.example() method. Why does this happen? I want the ClassB method to throw the exception in specific cases, and signify that it sometimes throws exceptions with throws ExampleException(), so why does ClassA not compile. To solve it, I can't add a throws statement onto ClassA.example() because it would violate ClassAInterface. And if I just wrap ClassB.exampleTest() in a try catch statement, much of the rest of ClassA.example() would throw errors because ClassB signifies something is wrong and you should throw an exception at that point, which is the entire point of throwing an exception`. So I'm not sure why this is happening or how to solve it.

Why does the code refuse to compile?
It's quite normal. As you said, B.exampleTest() sometimes throws an exception. A.example() calls B.exampleTest() and does not catch any exception. So, even if the exception doesn't always happen, it happens sometimes. And when it happens the exception is also thrown by A.example(). So it has to be declared or caught. Just like B.exampleTest() sometimes throws an exception, A.example() also sometimes throws the same exception.
Now, what to do? You have 3 choices:
declare that the exception is thrown: the caller of A.example() will then have to decide what to do in that case.
catch it inside A.example(), and deal with it somehow.
catch it, wrap it inside a runtime exception (which doesn't have to be declared in the throws clause), and throw this runtime exception. The caller will have to deal with this runtime exception, but won't have any hint from the compiler that an exception can be thrown.

Related

Javac/Eclipse - Warning if a method doesn't throw the most specific Exception it could

I have a class like this:
public class FooBar
{
public String foo() throws Exception {
return "";
}
public String bar() throws Exception {
throw new BazException();
}
}
Inside a eclipse, I get a warning on method foo stating:
The declared exception Exception is not actually thrown by the method foo() from type FooBar
See below:
Question: Is it possible to configure a silmiar warning for method bar? Method bar doesn't throw the most specific exception that it could.
I am using:
Eclipse Oxygen Release (4.7.0)
Java 8
Your post is raising two distinct issues. First issue:
Is it possible to configure a similar warning for method bar?
Yes, though no configuration is needed. If a method declares that it throws some sub-type of Exception but actually doesn't, then a similar warning to the one you report will be displayed in Eclipse. There is nothing special about an exception of type Exception with regard to that warning.
In your code just change method foo() to throw BazException instead of
Exception to see that:
Second issue:
Method bar doesn't throw the most specific exception that it could.
That is true, but is an issue distinct from getting a message about an exception not being thrown at all. There is no way to configure Eclipse to throw a message like "The method {m} does not throw the most specific exception that it could" since there is no message along those lines in Eclipse's list of compiler Errors/Warnings.
Besides, the wording of such a message could get tricky and convoluted in a complex method that threw multiple exceptions. Perhaps a code analyzer tool such as PMD could identify offending methods for you.
No, Eclipse only displays a warning in the first case, because throwing an exception that can never occur is a code smell, whereas throwing a more general exception is not a code smell.
Throwing an exception that can never occur
This forces the caller unnecessarily to handle the exception, for example:
public class Foo {
public static void main(String[] args) {
Foo foo = new Foo();
try {
System.out.println(foo.foo());
} catch (IOException e) {
// unreachable code
}
}
public String foo() throws IOException {
return "";
}
}
For simplified exception handling, some people prefer to add generally the throws Exception or the throws Throwable declaration to almost any method. Therefore, the warning can be configured to ignore these special cases: in Project > Properties: Java Compiler > Errors/Warnings, section Unnecessary code > Unnecessary declaration of thrown exception uncheck Ignore 'Exception' and ' Throwable'.
Note, if an interface method has a throws declaration, the implementing class does not need to have also a throws declaration:
public class Foo implements IFoo {
public String foo() {
return "";
}
}
interface IFoo {
String foo() throws IOException;
}
Throwing a more general exception
A more general exception is useful if you want to hide details from the caller (for the same reasons you should prefer List list = new ArrayList(); over ArrayList list = new ArrayList(); in most cases). It gives you more flexibility to change the code of the method without having to modify the code of the caller.
However, maybe you can create problems markes with SpotBugs, Checkstyle, PMD or similar plug-ins for that. If at all, I would recommend to do this only for private methods.

Java Custom Exception on Class Level

Can we create an custom exception for a class Level.
For example I have a Class A, now when I create a given object or When I call a given method, I would like yo throw my custom exception.
This is the easiest way to create your own Exception:
public class LevelException extends Exception {
public LevelException(String message) {
super(message);
}
}
You have two kind of exceptions checked and unchecked exceptions.
Unchecked exceptions are the sub classes of RuntimeException, those exceptions don't need to be added explicitly in your method/constructor description, calling code doesn't have to manage it explicitly with a try/catch block or by throwing it.
Checked exceptions are the sub classes of Exception but not the sub classes of RuntimeException, those exceptions need to be added explicitly in your method/constructor description, calling code have to manage it explicitly with a try/catch block or by throwing it.
Depending of your need, you will chose one of the two possibilities, if you want to enforce calling code to manage it, use checked exceptions otherwise use unchecked exceptions.
Unchecked exceptions
How to create it:
public class MyException extends RuntimeException {
...
}
How to use it:
public void myMethod() {
...
if (some condition) {
throw new MyException();
}
...
}
Checked exceptions
How to create it:
public class MyException extends Exception {
...
}
How to use it:
public void myMethod() throws MyException {
...
if (some condition) {
throw new MyException();
}
...
}
You can find more details about exceptions here

Need explanation on Exception code

I have some few doubts on exceptions.
Can anyone tell me why java doesnt allow us to create Checked Exception in a Subclass while it allows Unchecked exception in a subclass
Below exampple throws Compile time error when I use 'throws IOException' , BUT it doesnt throw any error when I use 'throws ArithmeticException' in a subclass.. I just wanna know the actual reason behind it, so can you please?
Here is code (you will get compile time error)
package com.exception.test;
import java.io.IOException;
public class Parent {
void msg() {
System.out.println("Parent...");
}
public static void main(String[] args) {
Parent parent = new Child();
parent.msg();
}
}
class Child extends Parent {
void msg() throws IOException {
System.out.println("Child...");
}
}
//using unCheckedException
package com.exception.test;
import java.io.IOException;
public class Parent {
void msg() {
System.out.println("Parent...");
}
public static void main(String[] args) {
Parent parent = new Child();
parent.msg();
}
}
class Child extends Parent {
void msg() throws ArithmeticException {
System.out.println("Child...");
}
}
If a subclass method declares it can throw a checked exception that the parent doesn't, it breaks the Liskov substitution principle, which is one of the corner stones of object oriented programming.
Consider this bit of code, with Child.msg declared to throw a checked exception:
void doMsg(Parent p) {
p.msg();
}
The program semantics break if you pass in a child object because the checked exception is now neither being caught nor thrown: the exception is no longer "checked."
Since unchecked exceptions can be thrown everywhere, declaring to throw one serves no other purpose than documentation. Therefore it can be allowed safely.
The msg() method in your parent class can throw any unchecked exception it likes. Hence, if you explicitly declare that your child throws an unchecked exception, you're not actually altering the contract. Your child method may throw an ArithmeticException, but so might your parent method.
Checked exception can be narrowed down while overriding, but not can't be broaden. Unchecked exception need not be caught by the overridden methods
From the java specs
The checked exception classes named in the throws clause are part of
the contract between the implementor and user of the method or
constructor. 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.
Unfortunately, you have hit yet another pitfall of Java's misfeature known as Checked Exceptions. The error you are receiving is an actual problem that all Java professionals face: you are implementing a method with some code that happens to throw a checked exception not declared by the superclass method. The declared checked exceptions are a part of the Java method signature; you can reduce the list in a subclass, but you cannot expand it.
If this is more that just a "why" question, and you need a workaround, the standard idiom is
try {
...code that throws the checked exception...
} catch (TheCheckedException e) { throw new RuntimeException(e); }
This is called exception wrapping. If you have more than one or two undeclared checked exceptions, you can also use the opposite idiom, ensuring that all declared exceptions propagate transparently and all undeclared ones get wrapped:
try {
...code that throws various checked exceptions...
}
catch (DeclaredEx1 | DeclaredEx2 | RuntimeException e) { throw e;}
catch (Exception e) { throw new RuntimeException(e); }

Advantage of declaring an exception

If I have a class called Boat, and if I write :
class Boat throws Exception
Inside my class I am using try catch block to catch ArithmeticException for instance.
What benefit there is to declare an exception versus not declaring an exception?
A class does not throw exceptions. Only methods do.
For some exceptions (checked exceptions that may occur in your code and that you do not catch) the compiler forces you to declare them.
You never have to declare RuntimeExceptions (such as ArithmeticException), but you can. This serves as documentation.
You can declare checked exceptions that your code does not throw. This makes it future-proof if you might later want to throw them, and also allows for subclasses to do such.
When declaring exceptions, you can go broad/generic (throws Exception or even throws Throwable), but it is generally better to be more specific. That gives the people using your code a better idea of what to expect. The whole purpose of having these many specific Exception classes is to make it easier to handle exceptions appropriately (and have the compiler enforce the fact that someone at least thought about doing that).
First classes won't throw Exception, only methods will throw
check this Example
class A
{
public A() throws Exception
{
int k=5/0;
}
}
public class B
{
public static void main(String[] args)
{
A a=new A();
}
}
When you run the above you'll get compile time error saying
Unhandled exception type Exception
because when ever methods throws exception , they are expected to handle by calling object, it is just like saying 'Hey somebody handle Exception', so the method calling it should handle the Exception , if they don't it will be a compile time error.
For the smooth execution of program, Exception thrown by method should be handle by calling method. Here is how you need to handle.
class A
{
public A() throws Exception
{
int k=5/0;
}
}
public class B
{
public static void main(String[] args)
{
try{
A a=new A();
}
catch(Exception e)
{
System.out.println("caught "+e);
}
}
}
Declaring Exception will allow your program to compile if any Exception can be determined by the compiler to "escape". It's primary purpose, though, is to document to the user of your method (and to their compilers) that it may throw an Exception.
As such, declaring Exception, vs declaring a more specific exception cause, is nullifying the benefits of the scheme -- cheating.
If you write something like that,
double x = 1/0;
System.out.print("hey");
it will give you an exception and your code is going to stop, will not print hey. But if you encapsulate it with try/catch, it will not stop.
try{
double x = 1/0;
}catch(ArithmeticException){}
System.out.print("hey");
This will print hey.

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