I am a little bit confused with exceptions in Java and when to use which particular style of implementation.
I used IllegalArgumentException as an example, but the main point I would like to address is when does one throw, extends or throw new exception?
Also as an additional point I have an assignment where I have to create a java class and the spec vaguely states that the constructor should throw an IllegalArgumentException so which one would be the best to use?
public class Test{
//when does one use this type of exception
public Test(String yourName) throws IllegalArgumentException{
//code implemented
}
//when does one use this type of exception
public Test(String yourName) extends IllegalArgumentException{
//code implemented
}
public Test(String yourName){
if(yourName.length() <= 0){
//why not use this type of exception instead
//and what happens when I use this type of exception
throw new IllegalArgumentException("Please Enter Your Name..!");
}
}
}
Thanks in advance.
When some Exception occurs, you have two ways of handling it: doing throws from the method or doing try-catch. The first one looks like this:
public class MyClass {
public void myMethod() throws IllegalArgumentException {
someOtherMethod();
}
}
In this case you know that someOtherMethod() can throw an exception and you don't want to handle it - you just pass it further. After that, the invoker of myMethod() should take care of the Exception.
But the second way is when you handle it by yourself:
public void myMethod() {
try {
someOtherMethod();
} catch (Exception e) {
System.out.println("You've got an exception!");
}
}
About throwing exceptions manually - you may suppose that you do it in someOtherMethod(). When you do throw new IllegalArgumentException("Please Enter Your Name..!"); the program stops with a message about this exception (unless you handle it in a try-catch way).
And at last, you extend some exception, when you create your own Exception class:
class MyException extends IllegalArgumentException {
...
}
In this case you may do throw new MyException(); in your code.
I'd advise you to read more about exceptions in Java to understand what is going on. You may start with this lesson.
To ensure that you don't end up creating exceptions which already have equivalent in the standard library, I normally have a peek at the documentation before creating new exceptions. Also, it's very easy to go crazy with really big exception hierarchies if you are not careful. Don't create new exceptions just because you think you need to throw one somehow; create one because a code somewhere down the call stack would be doing something useful/different with that exception.
public Test(String yourName) throws IllegalArgumentException
You normally never specify runtime exception in the throws clause though it might be helpful if you need this information to be part of the public API.
public Test(String yourName) extends IllegalArgumentException
This doesn't look right and isn't valid Java.
I would only create a new exception type when you need to. You need a new type when you expect the caller to have catch clause for your new exception.
you can create new exceptions just to be more descriptive but that is what I use the message for.
Related
I'm trying to get into exception handling via custom exceptions.
I'm creating the class CustomExceptions and extending Exception as follows:
public class CustomExceptions extends Exception{
public CustomExceptions (String s) {
super(s);
}
However, rather than having to create multiple files for every custom exception I want, or bloating my main class file, I'd like to put all of my custom exceptions in this class and invoke them via a method
So let's say that I want to handle 2 situations: When the user tries to input a seat reservation, but the seat is already taken, and when the user tries to provide a ticket for someone outside of the age range.
Can I create 2 methods inside of the CustomExceptions class which invoke the constructor passing a custom message to it?
public void seatTaken(String s) {
String s = "The seat is taken, please choose a new one";
CustomExceptions(s);
}
public void notOldEnough(String s) {
String s = "User is not old enough for this movie.";
CustomExceptions(s)
}
}
Would this work? Or am I forced to create multiple custom exception files?
Generally custom exceptions should be defined in the top level. Because, almost universally, these exceptions are part of the interface of the package or module.
If the user cannot see them, then how are they going to catch them separately? And if you don't want to catch them separately, then why would you need separate classes?
However, if you must, you can include them into a class for which they are required:
public class SeatReservationSystem {
public static class ReservationFailedException {
... constructors taking a message ...
}
public static class SeatTakenException extends ReservationFailedException {
... constructors taking a message ...
}
public static class OutsideAgeException extends ReservationFailedException {
... constructors taking a message ...
}
....
}
After that you can create any method that returns them as required. Don't create methods that throw them as the compiler won't see those as exit points of the block you're in, and you'll get strange situations.
Here is some code to show what I mean:
// wrong
public static void throwRuntimeException() throws RuntimeException {
throw new RuntimeException();
}
// correct, but dangerous
public static RuntimeException createRuntimeException() {
return new RuntimeException();
}
public static void main(String[] args) {
String initializeMeOrThrowException;
if (new Random().nextBoolean()) {
// compiler doesn't recognize that the method always throws an exception
throwRuntimeException();
// this the compiler can understand, there is an explicit throw here:
// throw createRuntimeException();
// but this is the pitfall, it doesn't do anything:
// createRuntimeException();
} else {
initializeMeOrThrowException = "Initialized!";
}
// Compiler error for throwRuntimeException and createRuntimeException without throws:
// "The local variable initializeMeOrThrowException may not have been initialized"
System.out.println(initializeMeOrThrowException);
}
However, experience learns me that I forget the throws statement for the throw createException(...); method, and the stupid compiler doesn't warn me about that (even though the statement is utterly useless without it). So I try and not use either.
Note that I'm not certain if you should use exceptions for this. If your system is a reservation system, then refusing tickets is not that exceptional. Returning a ReservationResult makes more sense.
I use exceptions to flow control a lot, but I have a strange feeling that I am doing something wrong. Is it a good practice to write something like code shown bellow?
public static void main(String[] args)
{
try
{
methodA();
}
catch (Exception ex)
{
handleException(ex);
}
}
public static methodA()
{
methodB();
}
public static methodB()
{
if(someConditionIsNotMet)
{
throw new RuntimeException("Some Condition Is Not Met");
}
}
I use exceptions to flow control a lot
Throwing specific and functional exceptions to indicate a functional issue during the workflow is not bad itself.
It is not the single way to do it but it is a valid way.
Another way relies on methods that returns boolean and testing the returned value.
Personally, I don't use this way as I found it rather verbose, error-prone (we have not to forget to test the returned boolean) and less expressive (it has only two values: true and false) than an exception (it may have as many as required).
Suppose that method B has to check something and that if the check fails the processing should be stopped and the client notified of the issue, it would be totally valid to use exceptions for this purpose.
Now, it would make more sense to make the exception a specific exception rather than Exception.
Otherwise how the client could interpret the exception meaning ?
The exception could be a workflow exception but it could be also any exception thrown at runtime for another reason such as a NullPointerException.
You want to handle workflow exceptions in a specific way while you will not apply a specific processing to other thrown exceptions.
For example you could write something as :
public static methodA()
{
methodB();
}
public static methodB(){
if (!expectedDataFound()){
throw new DataNotFoundException("data xxx was not found");
}
if (!hasRights()){
throw new PermissionException("user xxx has not the rights for yyy");
}
}
Then from the client side, you have two ways.
Catching each exception individually or catching them in a common way (that is possible only if they make part of the same hierarchy).
Catching each exception individually :
public static void main(String[] args)
{
try
{
methodA();
}
catch (DataNotFoundException ex)
{
handleDataNotFoundException(ex);
}
catch (PermissionException ex)
{
handlePermissionException(ex);
}
}
Catching exception globally:
public static void main(String[] args)
{
try
{
methodA();
}
catch (WorkflowException ex)
{
handleWorkflowException(ex);
}
}
I think you are too harsh on yourself with saying that you "use exceptions to control flow". It is an antipattern to use exceptions for control flow, but in your example you do not.
Let's say that you have a method that sets the age for the user, and of course if the caller provided negative number, you should not complete the action. So a very reasonable way to ensure that, would be:
public void setAge(int age) {
if(age <0) {
throw new InvalidArgumentException("Age has to be zero or positive number");
}
}
If you prefer not to use exceptions maybe you can use features of the language such as Optionals or create response structure that handles both success and errors. For example, lets say you have a method that retrieves employees
public EmployeesOverview getEmployees() { ... }
Your response class could look like this:
public class EmployeesOverview {
private Ok ok;
private Error error;
class Ok {
private Set<Employee> employees;
}
class Error {
private String errorMessage;
}
}
So without throwing exception your method will provide clients with results or if there is a problem, the client will be informed about it.
I would separate flow control and exception handling. Flow control is meant for making sure statements are executed in correct sequence and under correct conditions. This must be determined at design time. Exception handling is meant to handle unforeseen situations at run time. Exceptions are almost always due to external factors: time outs, no disk space, data errors...
Just my two cents.
I have the below interface
public interface Interface1 {
Object Execute(String commandToExecute) throws Exception;
}
which then I 'm trying to mock so I can test the behaviour of the class that will call it:
Interface1 interfaceMocked = mock(Interface1.class);
when(interfaceMocked.Execute(anyString())).thenThrow(new Exception());
Interface2 objectToTest = new ClassOfInterface2(interfaceMocked);
retrievePrintersMetaData.Retrieve();
But the compiler tells me that there is an unhandled exception.
The definition of the Retrieve method is:
public List<SomeClass> Retrieve() {
try {
interface1Object.Execute("");
}
catch (Exception exception) {
return new ArrayList<SomeClass>();
}
}
The mockito documentation only shows uses of RuntimeException, and I have not seen anything on similar on StackOverflow.
I'm using Java 1.7u25 and mockito 1.9.5
Assuming your test method doesn't declare that it throws Exception, the compiler's absolutely right. This line:
when(interfaceMocked.Execute(anyString())).thenThrow(new Exception());
... calls Execute on an instance of Interface1. That can throw Exception, so you either need to catch it or declare that your method throws it.
I would personally recommend just declaring that the test method throws Exception. Nothing else will care about that declaration, and you really don't want to catch it.
You can use doAnswer method of Mockito to thrown checked exceptions, like this
Mockito.doAnswer(
invocation -> {
throw new Exception("It's not bad, it's good");
})
.when(interfaceMocked)
.Execute(org.mockito.ArgumentMatchers.anyString());
You shouldn't be having a problem if your method returns something and throws your error. Now if your method returns void you won't be able to throw an error.
Now the real thing is that you're not testing that your interface throws an exception, instead what you're testing what happens when an exception is thrown within this method.
public List<SomeClass> Retrieve() {
try {
interface1Object.Execute("");
}
catch (Exception exception) {
return handleException(exception);
}
}
protected List<SomeClass> handleException(Exception exception) {
return new ArrayList<SomeClass>();
}
Then you just call your handleException method and make sure it returns the correct thing. If you need to make sure that your interface is throwing an exception, then that is a different test for your interface class.
It might seem sucky that you are having to make a method for a single line but that's what happens sometimes if you want testable code.
I'm looking to clean up the exception mess that is currently the code base I'm working on.
The basic setup is this.
I have an interface that is implemented by a lot of classes that looks like this:
public interface TerminalMessage<E> {
// Override for specific return data type.
public E send(TerminalStream stream) throws Exception;
}
These classes throw a lot of different exceptions, like IOException, InterruptedException etc.
As it is now, all I do is call getMessage() on the catched exceptions and relay this message to the ui-code.
This is not very nice since I sometimes get bogus messages displayed to the user and I catch unwanted exceptions.
I'm thinking of creating a custom exception class (TerminalException) that would wrap all these kinds of exceptions.
However I'm not sure where to do the wrapping, should the wrapping be done where the exception is first thrown (in the output stream for example) or in every send() method. The former has the advantage of not adding much code, but it makes more sense to me that a stream throws IOException rather than a TerminalException.
The above design also doesn't really solve the sometimes bad messages displayed to the user, so some tip on how to transform the thrown exceptions into something useful to the user would be great!
Thanks!
a custom exception is a very good idea if you have useful information in it like an error code.
just wrap everything with your TerminalException, but do not forget the cause
OR
use the first TerminalException thrown:
public class MyException extends Exception{
String errorMessage;
public MyException(String message, Exception cause){
super();
if(cause instanceof MyException){
// already wrapped
errorMessage= cause.getErrorMessage();
initCause(cause.getCause());
}
else{
// not my Exception
errorMessage=message;
initCause(cause);
}
ยด
}
}
Another option could be to use a Template Method Design Pattern and "control" the exeptions therein as follows:
public abstract TerminalMessage<E> {
public abstract E doSend(TerminalStream stream);
public E send(TerminalStream stream) throws Exception {
// do common stuff here
try {
doSend(stream);
}
// catch more specific exceptions first
// handle all the exceptions accordingly here, thus controlling
// in one central location what will be thrown externally
catch(Exception) {
}
}
}
This way the exception handling for all of the derived classes will be the same and and localized, and the derived classes wont have to do anything special.
From many designs I have tried, this is the final one which I happily use on some projects.
public enum ExceptionCodes {
IOException("ioexception", false),
UserNotFound("usernotfond", true);
private static final String BUNDLE_NAME = "SOME_bundle_name";
private final String bundleCode;
private final String isManagable;
ExceptionCodes(String bundleCode, String isManagable) {
this. ...
...
}
public String message() {
// eventually get locale from somewhere, for example some threadLocal
return SomeBundleResolver.resolve(BUMDLE_NAME, bundleCode);
}
public Boolean isManagable() {
return isManagable;
}
}
public class MyGenericException extends RuntimeException {
private final ExceptionCodes exceptionCode;
private final Throwable throwable;
public MyException(ExceptionCodes exceptionCode) {
this....
...
}
public MyException(ExceptionCodes exceptionCode, Throwable throwable) {
this. ...
....
}
public Boolean isManagable() {
return exceptionCode.isManagable();
}
public String getMessage() {
return (throwable == null) ? super.getMessage() : throwable.getMessage();
}
...
}
Point is that exception codes are managed at one place. You can add custom atributes to enum like error codes etc. One of the many problem with exceptions is that if you do not know how to handle exception at place it is unprobable you will know how to handle exception layer above. Then just two cases can occur. Either exception can be displayed in some format to user, or system has to crash in some gracefull way. Attribute isManagable is exactly about this. If exception si not managable system must go down. So the exception is handled just at top level of application in general error handler. This way you can prevent Exception explosion.
This question already has answers here:
How can I write custom Exceptions?
(5 answers)
Closed 3 years ago.
I would like to create a custom exception in Java, how do I do it?
...
try{
...
String word=reader.readLine();
if(word.contains(" "))
/*create custom exception*/
}
catch(){
When I create my custom exception with throw new..., I obtain the error unreported exception...must be caught or declared to be thrown
You should be able to create a custom exception class that extends the Exception class, for example:
class WordContainsException extends Exception
{
// Parameterless Constructor
public WordContainsException() {}
// Constructor that accepts a message
public WordContainsException(String message)
{
super(message);
}
}
Usage:
try
{
if(word.contains(" "))
{
throw new WordContainsException();
}
}
catch(WordContainsException ex)
{
// Process message however you would like
}
You need to create a class that extends from Exception. It should look like this:
public class MyOwnException extends Exception {
public MyOwnException () {
}
public MyOwnException (String message) {
super (message);
}
public MyOwnException (Throwable cause) {
super (cause);
}
public MyOwnException (String message, Throwable cause) {
super (message, cause);
}
}
Your question does not specify if this new exception should be checked or unchecked.
As you can see here, the two types are different:
Checked exceptions are meant to flag a problematic situation that should be handled by the developer who calls your method. It should be possible to recover from such an exception. A good example of this is a FileNotFoundException. Those exceptions are subclasses of Exception.
Unchecked exceptions are meant to represent a bug in your code, an unexpected situation that you might not be able to recover from. A NullPointerException is a classical example. Those exceptions are subclasses of RuntimeException
Checked exception must be handled by the calling method, either by catching it and acting accordingly, or by throwing it to the calling method. Unchecked exceptions are not meant to be caught, even though it is possible to do so.
Great answers about creating custom exception classes. If you intend to reuse the exception in question then I would follow their answers/advice. However, If you only need a quick exception thrown with a message then you can use the base exception class on the spot
String word=reader.readLine();
if(word.contains(" "))
/*create custom exeception*/
throw new Exception("My one time exception with some message!");
}
As a careful programmer will often throw an exception for a special occurrence, it worth mentioning some general purpose exceptions like IllegalArgumentException and IllegalStateException and UnsupportedOperationException. IllegalArgumentException is my favorite:
throw new IllegalArgumentException("Word contains blank: " + word);
Since you can just create and throw exceptions it could be as easy as
if ( word.contains(" ") )
{
throw new RuntimeException ( "Word contains one or more spaces" ) ;
}
If you would like to be more formal, you can create an Exception class
class SpaceyWordException extends RuntimeException
{
}
Either way, if you use RuntimeException, your new Exception will be unchecked.
An exception is a class like any other class, except that it extends from Exception. So if you create your own class
public class MyCustomException extends Exception
you can throw such an instance with
throw new MyCustomException( ... );
//using whatever constructor params you decide to use
And this might be an interesting read
You just need to create a class which extends Exception (for a checked exception) or any subclass of Exception, or RuntimeException (for a runtime exception) or any subclass of RuntimeException.
Then, in your code, just use
if (word.contains(" "))
throw new MyException("some message");
}
Read the Java tutorial. This is basic stuff that every Java developer should know: http://docs.oracle.com/javase/tutorial/essential/exceptions/
You have to define your exception elsewhere as a new class
public class YourCustomException extends Exception{
//Required inherited methods here
}
Then you can throw and catch YourCustomException as much as you'd like.
You can create you own exception by inheriting from java.lang.Exception
Here is an example that can help you do that.