I am curious about if I should add throws ExceptionClass or not after the method's signature.(ExceptionClass extends RuntimeException)
For instance:
public void foo() // throws ExceptionClass
{
// ...
throw new ExceptionClass("");
}
If you use the JDK as a guidance, RuntimeException are not in the methods signature but are documented in the javadoc. You can have a look at collections for example.
Ideally you don't need to add runtime exception in method's throws clause. Since you want the consumer of this method to be aware of chances that this method may throw exception , i would say use javadoc either. Below is example of how you should use :
/**
*
* #throws ExceptionClass
*/
public void foo()
{
// ...
throw new ExceptionClass("");
}
Runtime exceptions do not need to be listed in the throws clause. Place it there only if you need to document this behaviour, if it's in some way important to know for the client of this class, that this exception might appear (but if that's the case, perhaps it needs to be changed to a checked exception, or only be mentioned in the javadocs).
Related
I have the following code:
public User getUserById(Long id) {
checkUserExists(id);
return repo.findOne(id);
}
private void checkUserExists(Long id) {
if (id == null || !repo.exists(id)) {
throw new NoUserFoundException("No User exists with id: " +id);
}
}
According to Oracle:
"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."
Do I have to describe the exception anyway in the JavaDoc (Without the #throws clause, but only describe?) What is the best way to describe such an unchecked exception in JavaDoc?
You are writing Javadoc for the user of your method. If it's useful for that user to know that it may throw an exception, document it!
In your case, it seems that it is indeed useful for the user to know that a NoUserFoundException is thrown if the user is not found.
In other cases it's less useful. For example, in many cases the fact that a NullPointerException is thrown if a parameter is null is not documented in the Javadoc because it's often somehow implied that a parameter cannot be null.
By the way, Oracle is talking about the throws class appearing after the method declaration, not about the Javadoc. If you decide to document a non-checked exception, it makes sense to use the #throws clause.
I am bridging a C Api to a Java Api. The C Api uses error codes for exceptional cases. Since every function returns such a error code and there are a lot of error codes (about 100), i wrote a error code handler that translates the error codes to a bunch of more general runtime exceptions:
public class ErrorCodeHandler {
public static void handle(int status) {
switch(status) {
case SUCCESS:
return; // In case of success, simply return
case NO_VALID_DATA:
throw new DataError("No valid data");
...
case NO_CONNECTION:
throw new ConnectionError("No connection");
}
}
}
All my custom Exception classes inherit from a base Exception class specific to my application:
public class MyException extends RuntimeException { ... }
public class DataException extends MyException { ... }
...
My methods simply call handle on the error code returned from the call to the C API:
public void someMethod() {
int status = cBinding.someMethod();
ErrorCodeHandler.handle(status);
}
If an error occured, the method will throw the appropriate exception. If not, it will simply return.
Now i am faced with the problem on how to document this kind of exception handling. I read that you don't add runtime exceptions as a throws clause, but document it using the Javadoc #throws tag.
Now my question is, should i add a #throws tag for every different exception i know can be thrown from a method (indirectly by looking up the possible error codes), or should i just document a generic #throws MyException? I feel like the first approach will clutter my documentation with a lot of mostly useless #throws tags (a lot of these error codes are very rare) and it will be a very high effort to document these. The second approach would be mostly copy-pasting, but i would lose the advantage the exception hierarchy gives me.
Has anyone ever done something similar? Any advice on how to document this kind of stuff?
It is perfectly reasonable to just write something like #throws MyException if underlying service fails in your javadoc. It’s fairly common in Java SE; for example:
Files.copy only has #throws clauses for IOException and two subclasses of IOException, even though it can throw many other subclasses of IOException.
The JDBC method Statement.execute has a #throws clause for SQLException and one subclass of SQLException, even though there are many other subclasses of SQLException that can be thrown.
I'm developing a library and in some method I want to throw a ClassNotFoundException but eclipse force me to either 'Add a throws declaration' or 'Surround with try/catch'. I do not want to implement any of them, what I want is to throw this excepcion to the client of the class. I've seen that all classes that extend ReflectiveOperationException force me to add or surround the exception. In the other hand I've seen that classes that extend RuntimeException does not require to add or surround the exception.
As an abstraction of my problem, imagine a code like this:
public Class getClassForCellType(int cellTypeRequested) {
Class cellClassRequired = null;
if (cellTypeRequested == 0) {
cellClassRequired = CellA.class;
} else if (cellTypeRequested == 1) {
cellClassRequired = CellB.class;
} else {
throw new ClassNotFoundException("cellType Not Available");
}
return cellClassRequired;
}
I want to throw ClassNotFoundException because is what is happening and I would not like to use another more generic class. Someone could please explain me why those ReflectiveOperationException classes require handling them directly.
I think your problem arises because you are not using ClassNotFoundException for the purpose it is intended. This exception is very specifically intended to be thrown when the implementation of a requested Java class is not available on the classpath.
Here you are trying to translate a parameter into a Class, but that is not the same as the system level error of a missing Class definition.
I would create your own CellTypeClassNotResolvedException which extends RuntimeException and throw that instead:
public CellTypeClassNotResolvedException extends RuntimeException {
public CellTypeClassNotResolvedException(String s) {
super(s);
}
}
Eclipse is telling you (as any Java compiler must do) that if you want a ClassNotFoundException to be able to escape your method, the method must declare that that is a possibility, like so:
public Class getClassForCellType(int cellTypeRequested) throws ClassNotFoundException {
// ...
throw new ClassNotFoundException("cellType Not Available");
// ...
return cellClassRequired;
}
This is the rule for any Exception other than java.lang.RuntimeException and its subclasses.
You need to add a throws declaration due to ClassNotFoundException being a checked exception. TO fix your code, it would look like this:
public Class getClassForCellType(int cellTypeRequested) throws ClassNotFoundException {
Class cellClassRequired = null;
if (cellTypeRequested == 0) {
cellClassRequired = CellA.class;
} else if (cellTypeRequested == 1) {
cellClassRequired = CellB.class;
} else {
throw new ClassNotFoundException("cellType Not Available");
}
return cellClassRequired;
}
In Java, we have two core types of exceptions:
Checked, and unchecked exceptions.
Checked exceptions: If this type of exception is thrown, it has to be explicitly handled by either the client of the method or the method itself. ReflectiveOperationException is an example of this. These types of exceptions are usually used to reflect API problems, usage problems, legitimate/business application failures.
Java's way of fulfilling this requirement is to say you either have to handle (i.e. catch the exception) in your method, or you have to explicitly inform the client that they may get this exception (i.e. throws clause).
Unchecked exceptions: If this type of exception is thrown, it does not have to be handled explicitly. These are usually reflective of programming errors - for instance, ArrayIndexOutOfBoundsExceptions is a good example - you wouldn't anticipate running into this problem, and if you did, you can be relatively confident it's a bug and don't expect the client to cater for it in their code!
In your example, you are trying to tell the client that they passed you a bad parameter by throwing the ClassNotFoundException. They need to know this might be thrown in order to handle the scenario in their code, hence you need to add the throws declaration to the method signature.
public Class getClassForCellType(int cellTypeRequested) throws ClassNotFoundException {
}
See Oracle Docs on more exception tutorials: http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
I have method1() which is called from lots of other methods throughout the code. This is the signature of the method:
public void method1(final Properties properties) throws IOException {}
All methods calling this method also throw IOException.
The actual code in method1() changed, so now instead of IOException it throws some other exceptions that extend Exception and not IOException anymore.
I don’t want to change the signature of all methods calling method1().
Is it ok to create IOException and still throw IOException from method1() and hence the methods calling method1()?
Something like below:
Try {
// code
} catch (Exception e) {
throw new IOException(e.getCause());
}
No, you should not do this, because you will confuse every other developer reading your code or reading stacktraces.
From the software-design point of view, the error happened a lot earlier.
If your code is like an API and used by others, you may better have used Custom-Exceptions and wrapped the IOException as root-cause.
If you have the complete source, you should refactor the source and add another exception signature.
You need to save the original exception as the cause, so you're not losing the original message or stacktrace. Calling e.getCause() in your code example is skipping over the exception that you caught and getting its cause, which is suspicious-looking.
Also it would be better to specify the particular exceptions that the method catches, rather than using a catch-all Exception type. Catching Exception would result in things like NullPointerExceptions getting caught that were not trapped before.
The best thing to do here is change the exceptions thrown by your method to a custom type that doesn't let the implementation details bleed through to the callers. Your method signature should change to
public void method1(final Properties properties) throws SomeCustomException {
try {
.... // do whatever
} catch (AException | BException | CException e) {
throw new SomeCustomException(e);
}
}
This will work technically.
However, catching Exception or Throwable is almost everytime a bad idea (as is throwing them), because you will also catch all other Exceptions, besides RuntimeExceptions.
If you can change the code of all calling classes (i.e. you are not developing a framework/library), you should do so. Because I assume you meant method1() throws a more specific type now.
You may also think about throwing a Subtype of RuntimeException which does not need to be catched, and is a good idea for errors that can't be corrected (e.g. a bad configuration).
(see Clean Code by Robert Martin)
A few of my methods in Java throw exceptions such as NoSuchElementException, IllegalArgumentException, etc. But when using these methods, these exceptions appear to be unchecked. In other words, caller of my methods is not required to do a try/catch on my methods that throw those exceptions. I read around it seems that Exceptions by default are "checked" and only Errors are the ones "unchecked". But somehow, the exceptions I throw are also unchecked. It is weird.
How can I ensure that when my method throws an exception, the caller MUST catch the exception at compile time? Simply said, how can I throw a checked exception?
Thanks!
Only RuntimeException and its subclasses are unchecked. (Well, Error and its subclasses are as well, but you shouldn't be messing with Errors.) All you need to do to throw a checked exception is ensure that it doesn't extend RuntimeException.
See this hack, it might help (hope it's not OT).
public class Test {
// No throws clause here
public static void main(String[] args) {
doThrow(new SQLException());
}
static void doThrow(Exception e) {
Test.<RuntimeException> doThrow0(e);
}
#SuppressWarnings("unchecked")
static <E extends Exception> void doThrow0(Exception e) throws E {
throw (E) e;
}
}
Whether an exception is checked or not checked is NOT how you throw it or declare it, it is only dependent on whether the exception you choose is derived from RuntimeException or not. The ones you list above, all are derived from RuntimeException and so clients of your method do not need to catch them.
All sub-classes of Throwable are checked except sub-classes of Error and RuntimeException. (You can sub-class Throwable directly)
The compiler checks these Exception, however they have no special place at runtime. i.e. you can throw a checked Exception without the compiler knowing and it will behave normally.
e.g.
public static void throwChecked(Throwable t) /* no throws clause */ {
Thread.currentThread().stop(t);
}
public static void main(String... args) /* no throws clause */ {
throwChecked(new Throwable());
}
This compiles and prints the Throwable as you might expect.
I think you should take a step back and learn the theory behind why to throw a checked exception vs an unchecked exception. The Java tutorial on exceptions is a good resource.
From the page entitled Unchecked Exceptions — The Controversy:
Runtime exceptions represent problems that are the result of a programming problem, and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way.
Exceptions that extends RuntimeException do not have to be declared.
You can declare the method: throws Exception or even throws Throwable and that will have to be handled (though it is not advised).