I'm trying to define my own exception class the easiest way, and this is what I'm getting:
public class MyException extends Exception {}
public class Foo {
public bar() throws MyException {
throw new MyException("try again please");
}
}
This is what Java compiler says:
cannot find symbol: constructor MyException(java.lang.String)
I had a feeling that this constructor has to be inherited from java.lang.Exception, isn't it?
No, you don't "inherit" non-default constructors, you need to define the one taking a String in your class. Typically you use super(message) in your constructor to invoke your parent constructor. For example, like this:
public class MyException extends Exception {
public MyException(String message) {
super(message);
}
}
A typical custom exception I'd define is something like this:
public class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
public CustomException(String message, Throwable throwable) {
super(message, throwable);
}
}
I even create a template using Eclipse so I don't have to write all the stuff over and over again.
If you use the new class dialog in Eclipse you can just set the Superclass field to java.lang.Exception and check "Constructors from superclass" and it will generate the following:
package com.example.exception;
public class MyException extends Exception {
public MyException() {
// TODO Auto-generated constructor stub
}
public MyException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public MyException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public MyException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
}
In response to the question below about not calling super() in the defualt constructor, Oracle has this to say:
Note: If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass.
Reason for this is explained in the Inheritance article of the Java Platform which says:
"A subclass inherits all the members (fields, methods, and nested
classes) from its superclass. Constructors are not members, so they
are not inherited by subclasses, but the constructor of the superclass
can be invoked from the subclass."
package customExceptions;
public class MyException extends Exception{
public MyException(String exc)
{
super(exc);
}
public String getMessage()
{
return super.getMessage();
}
}
import customExceptions.MyException;
public class UseCustomException {
MyException newExc=new MyException("This is a custom exception");
public UseCustomException() throws MyException
{
System.out.println("Hello Back Again with custom exception");
throw newExc;
}
public static void main(String args[])
{
try
{
UseCustomException use=new UseCustomException();
}
catch(MyException myEx)
{
System.out.println("This is my custom exception:" + myEx.getMessage());
}
}
}
Exception class has two constructors
public Exception() -- This constructs an Exception without any additional information.Nature of the exception is typically inferred from the class name.
public Exception(String s) -- Constructs an exception with specified error message.A detail message is a String that describes the error condition for this particular exception.
If you inherit from Exception, you have to provide a constructor that takes a String as a parameter (it will contain the error message).
and don't forget the easiest way to throw an exception (you don't need to create a class)
if (rgb > MAX) throw new RuntimeException("max color exceeded");
Related
Here test is not throwing an Exception object , yet i had handled it . Since Exception is an checked exception shouldn't it throw a compiler error of unreachable code in the catch block
class Ece extends Exception {}
public class Excep {
public static void test() { }
public static void main(String[] args) {
try {
test();
} catch (Exception E) {
}
}
}
The class Exception has RuntimeException as subclass. RuntimeException and its subclasses do not need to be declared in methd signature.
In this case you are catching all possible subclasses of Exception, including all that subclasses that do not need signature declaration. If your test method throws for example ArrayIndexOutOfBoundsException you will be able to catch and handle it, yet test signature will not be affected.
Further reading here
I am looking for an elegant way to create a factory for dependency injection. In my case, the factory simply has to call a one-argument constructor. I found this answer outlining how to use a Function<ParamType, ClassToNew> for such purposes.
But my problem is: in my case, my ctor declares to throw some checked exception.
What I don't get: creating that Function using a method reference to that constructor doesn't work. As in:
import java.util.function.Function;
public class Mcve {
public Mcve(String s) throws Exception {
// whatever
}
public static void main(String[] args) {
Function<String, Mcve> mcveFactory = Mcve::new;
}
}
tells me about "Unhandled exception: java.lang.Exception" for Mcve::new. Although this code is not invoking the constructor.
Two questions:
why that error? The above code does not invoke the ctor (yet)?
are there any elegant ways to solve this puzzle? ( simply adding throws Exception to my main() does not help )
You need to provide a custom interface ThrowingFunction which has one method that throws Exception.
public interface ThrowingFunction<ParameterType, ReturnType> {
ReturnType invoke(ParameterType p) throws Exception;
}
public class Mcve {
public Mcve(String s) throws Exception {
// whatever
}
public static void main(String[] args) {
ThrowingFunction<String, Mcve> mcveFactory = Mcve::new;
}
}
Using this approach results in calling mcveFactory.invoke("lalala"); forcing you to handle the exception thrown by the constructor.
Reason for the error is that the actual function reference you want to store (not 100% sure about the terminology) throws an exception and therefore the types simply do not match up. If you could store Mcve::new inside a function then whoever calls the function no longer knows an Exception can be thrown. What would then happen if the exception would actually be thrown? Both throwing the exception and discarding it do not work.
Alternative: if you need to actually retrieve a Function<String, Mcve> in the end then you need to write a function (or lambda) that invokes the constructor, catches the exception and either discards it or rethrows it wrapped inside a unchecked RuntimeException.
public class Mcve {
public Mcve(String s) throws Exception {
// whatever
}
public static void main(String[] args) {
Function<String, Mcve> mcveFactory = parameter -> {
try {
return new Mcve(parameter);
} catch (Exception e) {
throw new RuntimeException(e); // or ignore
}
};
}
}
I would argue that the error message itself is at least a bit misleading since you normally see it when actually invoking the method. I can certainly understand the confusion resulting in the first sub-question. It would be clearer (sadly not possible) to state something like
Incompatible types Function<String,Mcve> vs. Function<String,Mcve> throws Exception.
I had to do that just recently... If you can change the class definition, you could use the infamous sneaky throws way of doing things:
static class OneArg {
private final String some;
#SuppressWarnings("unchecked")
public <E extends Exception> OneArg(String some) throws E {
try {
this.some = some;
// something that might throw an Exception...
} catch (Exception e) {
throw (E) e;
}
}
public String getSome() {
return some;
}
}
Function<String, OneArg> mcveFactory = OneArg::new;
I've been thinking about this for a while and indeed - if you want to have a Function that declares clearly your intention, I think that you need to have a Function that would extend the java.util.Function, something like this:
#FunctionalInterface
public interface ThrowingFunction<T, R> extends Function<T, R> {
R applyWithExc(T t) throws Exception;
#Override
default R apply(T t) {
try {
return applyWithExc(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
You can btw choose which method you call when you define your constructor reference - the one that would throw an Exception and one that would silently wrap it with a RuntimeException.
I have two classes inheriting from java.lang.Exception. They both have a method with the same signature void a(){...}. They both can be thrown in a code block. If I do:
catch (SubException1 | SubException2 e)
{
e.a();
}
Then it won't compile because method a() does not belong to Exception. Is it a Java language flaw? How should I design my code properly to prevent code redundancy?
When you catch multiple exception types in a single catch statement the inferred type of the caught exception is the greatest common denominator of those classes. In your case, the greatest common denominator is Exception, which doesn't have the method void a(). In order to make it accessible to the catch block you could either extract it to a common base class, or (arguably) more elegantly, define it in an interface that both classes implement:
public interface SomeExceptionInterface {
void a();
}
public class SomeException extends Exception implements SomeExceptionInterface {
// Implementation...
}
public class SomeException2 extends Exception implements SomeExceptionInterface {
// Implementation...
}
If you need to access a method called a(), you need a type that provides that method. A simple solution could be:
public class AbstractSubException extends Exception {
public abstract void a();
}
public class SubException1 extends AbstractSubException {
#Override public void a() { ... }
}
public class SubException2 extends AbstractSubException {
#Override public void a() { ... }
}
Then you can catch the way you did or (somewhat simpler):
catch (AbstractSubException e) {
e.a();
}
Maybe the code for the method a is the same in all sub classes. Then you can make it concrete and put the code into the parent class.
I have an interface
public interface DataDAO {
public void doSomething() throws Exception;
}
Lets say that there are two implementations, one that uses Database to get the data and another one that uses a Webservice.
public class DataDAOJdbc implements DataDAO {
public void doSomething() throws Exception {
//Implement
}
}
public class DataDAOWebService implements DataDAO {
public void doSomething() throws Exception {
//Implement
}
}
As you can already see, the problem is the super generic exception launched. As both implementations need to raise the same kind of exception.
The Jdbc implementation really only raises lets say SQLException while the Webservice implementation only rises the IOException.
Question is, how can I make the interface more elegant, so I capture a proper exception?
The first thing that I though was creating my own exception, and declare it on the interface level
public interface DataDAO {
public void doSomething() throws MyCoolException;
}
And then, of course implement accordinly.
Question is, does this make sense? I have never created my own exceptions, so I am not really sure if this makes much sense or not. Also, what should I take into account when creating MyCoolException?
The first thing that I though was creating my own exception, and declare it on the interface level (...) does this make sense?
Yes, it does makes sense and I would think it is the best way to handle these situations.
I'll provide a kickoff example for this (based on your current code):
public class MyCoolException extends Exception {
public MyCoolException() {
}
public MyCoolException(String message) {
this.message = message;
}
}
public interface DataDAO {
public void doSomething() throws MyCoolException;
}
public class DataDAOJdbc implements DataDAO {
public void doSomething() throws MyCoolException {
//Implement
try {
} catch (SQLException e) {
//handle the exception
logger.error("Error!", e);
//throw your custom exception
throw new MyCoolException(e.getMessage());
}
}
}
public class DataDAOWebService implements DataDAO {
public void doSomething() throws MyCoolException {
//Implement
try {
} catch (IOException e) {
//handle the exception
logger.error("Error!", e);
//throw your custom exception
throw new MyCoolException(e.getMessage());
}
}
}
You can use a generic type to define the interface thrown:
public interface DataDAO<E extends Throwable> {
public void doSomething() throws E;
}
Then your Implementations would look like this:
public class DataDAOJdbc implements DataDAO<JDBCException> {
public void doSomething() throws JDBCException {
//Implement
}
}
public class DataDAOWebService implements DataDAO<WebServiceException> {
public void doSomething() throws WebServiceException {
//Implement
}
}
However, this has the drawback that you can no longer handle all the exceptions the same way, unless you just catch Exception (which pretty much negates the entire point).
does this make sense?
Yes, it does. By declaring that doSomething throws a specific checked exception, you're signaling to callers of the method that they only need to catch and deal with that specific exception. By declaring plain throws Exception, callers would be encouraged to catch and deal with all Exceptions, which even include runtime exceptions like NullPointerException.
what should I take into account when creating MyCoolException?
It could be as simple as the following:
public final class MyCoolException extends Exception {
public MyCoolException(Throwable cause) {
super(cause);
}
}
So your custom exception would simply act as a wrapper for the cause exception, whatever it may be. If possible you could add a message with additional information that might be helpful for debugging. When MyCoolException is caught you can unwrap it by calling getCause(), or else pass it into a call to a logging framework (its stacktrace will include the cause exception).
I read this code where the interface throws an exception, but the class which implements it doesn't throw one or catch one, why is that? Is it legal or safe in java?
import java.rmi.*;
public interface MyRemote extends Remote {
public String sayHello() throws RemoteException;
}
import java.rmi.*;
import java.rmi.server.*;
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote{
public String sayHello() {
return "Server says, 'Hey'";
}
public MyRemoteImpl() throws RemoteException {}
public static void main (String[] args) {
try {
MyRemote service = new MyRemoteImpl();
Naming.rebind("RemoteHello", service);
} catch(Exception ex)
{
ex.printStackTrace();
}
}
}
A general rule of implementing and extending is you can make your new class or interface "less restrictive" but not "more restrictive". If you think of the requirement to handle an exception as a restriction, an implementation that doesn't declare the exception is less restrictive. Anybody who codes to the interface will not have trouble with your class.
— Stan James
As part of the discussion at http://www.coderanch.com/t/399874/java/java/Methods-throwing-Exception-Interface
If a Java method overrides another in a parent class, or implements a method defined in an interface, it may not throw additional checked exceptions, but it may throw fewer.
public class A {
public void thrower() throws SQLException {...}
}
public class B extends A {
#Override
public void thrower() throws SQLException, RuntimeException, NamingException {...}
}
SQLException is fine; it's declared in the overridden method. It could even be replaced by a subclass like SerialException.
RuntimeException is fine; those can be used anywhere.
NamingException is illegal. It isn't a RuntimeException, and isn't in A's list, even as a subtype.
Great answer by #Chetter Hummin.
One way to look at this, and I find it easy to remember, is interface's implementations can be more specific but not more general.
For example in interface void test() throws Exception means "test may throw exception"
then implementation can be void test() means "test will not throw exception" (more specific)
or implementation can be void test() throws NullpointerException (more specific)
interface x {
void testException() throws Exception;
}
public class ExceptionTest implements x {
#Override
public void testException() { //this is fine
}
////// or
#Override
public void testException() throws NullPointerException { // this is fine
}
}