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
Related
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");
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.
Catching an exception for a method which does not throw a subclass of exception in try block, fails to compile. when I catch Exception it works. How does it work??
This code below does not compile !!
class Test
{
public static void main(String[] args) {
try {
myMethod();
} catch(MyException ex) {//Does not compile
}
}
public static void myMethod() {}
}
class MyException extends Exception {}
But when Exception is caught, compiler does not complain.
class test
{
public static void main(String[] args)
{
try{
myMethod();
} catch(Exception ex) {//how does this works ??
}
}
public static void myMethod() {}
}
From the JLS (ยง11.2.3): (emphasis mine)
It is a compile-time error if a catch clause can catch checked
exception class E1 and it is not the case that the try block
corresponding to the catch clause can throw a checked exception class
that is a subclass or superclass of E1, unless E1 is Exception or a
superclass of Exception.
MyException is a checked exception. It was never thrown from your myMethod() method . So catch block will be unreachable.
But Exception is a super class of checked and unchecked(runtime) exception and if any runtime exception thrown from myMethod() it will be handled in catch block
which is a possible scenario. Hence there is no compilation error.
Assuming I have a #Stateless bean:
#Local
public interface A {
public void check() throws MyException {
}
#Stateless
public class AImpl implements A {
public void check() throws MyException {
...
try {
data = getDataFromService();
} catch (RException e) {
throw new MyException(e);
}
}
}
Exceptions:
public class MyException extends Exception{}
public class RException extends RuntimeException{}
When I am injecting this bean to some other class with the use of #EJB annotation and executing the check() method, I am getting EJBException with MyException as its cause...
public class B {
#EJB private A a;
public void start() {
try {
a.check();
} catch (MyException e) {
e.printStackTrace();
}
}
}
How can I make it throw proper exception?
Any ideas how to make it work ok?
Is there any way to make it work without intercepting the EJBException throw, and rethrowing its exception cause?
I assume your MyExceptionextends RuntimeException and therefore it is unchecked exception. in such case you can annotate your exception with #ApplicationException annotation. As a result of that your exception will be an application exception instead of a system exception. When a system exception is thrown it is packaged in EJBException, but application exceptions are thrown directly to the client.
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).