Have toString standard method inside my class that overrides Object ones.
Is it good practice to use try catch in this method?
#Override
public String toString() {
try {
return
"number='" + product.getProductNumber() +
", locale=" + locale;
} catch (ProductException e) {
return super.toString();
}
}
No, this is not normal practice. Exceptions should be used to handle exceptional situations, not the regular code flow.
Your code uses try/catch to detect situations that could be handled without introducing exceptions. It is roughly equivalent to the following method:
#Override
public String toString() {
if (product.checkProductNumber()) {
return "number='" + product.getProductNumber() +
", locale=" + locale;
} else {
return super.toString();
}
}
The imaginary checkProductNumber method returns true when getProductNumber call would not throw ProductException, and false otherwise. Making a method like checkProductNumber and using it instead of catching the exception is a better way of coding methods where exceptions are caught during the normal program flow.
Using Try/Catch in toString in not a normat practice but there is no restriction to use try/catch in toString method().
but if you want to remove try/catch in your code then you must have a knowledge that who throw this ProductException exception and what are the condition in which this exception is thrown.
If this is checked exception then in that case you can create temp method with boolean option to check whether this operation will run normally or throw an exception. As shown in #dasblinkenlight answer.
Note: best practice says that toString() method is always overridden in those classess who contains some data and in those type of classes getter/setter is only used for getting and setting values so there is no chance of exception.
If you want to do some opertion on data then try to do that outside of the this class. Use these type of classes to only contains data and don't perform operation inside the class(except small operation only if extremly required)
I don't see any obvious reason for not doing it like this. However your current proposal will loose the locale info if a ProductException is thrown. Unless you only want this OR the super.toString(), maybe you should do something like this:
#Override
public String toString() {
String number = null;
try {
number = product.getProductNumber();
} catch (ProductException e) {
number = "unknown: " + e.getMessage(); // or something like this
}
// here you may or may not include super.toString()
return super.toString() + ", number=" + number + ", locale=" + locale;
}
I haven't seen the usage of try-catch in toString. But if you are using some method which can throw the exception then I dont see any issue in using try-catch inside of toString
Yes there is nothing wrong with this.If you know that any exception will occur in toString() then you can use try-catch{ } in it.
If The method product.getProductNumber() may throw the ProductException it is the right way.
Related
I have a method that handles different error codes and always throws unchecked exception. This method is used in many places across the class. When I try to call it inside another method that has not void return type as shown below:
public Object someMethod() {
....
if(success){
return result;
} else {
callMethodThatAlwaysThrowsUncheckedExceptions();
}
}
java compiler says that the method is missing return statement.
Only two options come to my mind how to solve this problem:
replace method call with its content
add a return statement just after method call that returns an empty object
However I don't really like any of these options: the first one because of code duplication and the second one because of the need to write code that will never be executed.
Is there any other way to solve this problem?
Just swap around the terms, you'll never get to return if the method throws.
if(!success){
callMethodThatAlwaysThrowsUncheckedExceptions();
}
return result;
Or even
callMethodThatAlwaysThrowsUncheckedExceptions(succes);
return result;
Just check the success condition in your throwing method.
Next to the great answer already provided by Slawomir Chodnicki, here's another suggestion.
Change your callMethodThatAlwaysThrowsUncheckedExceptions() which somewhere throws an Exception into a factory method. E.g: change this:
// somewhere in callMethodThatAlwaysThrowsUncheckedExceptions
throw new MyException();
To:
return new MyException();
That way you can call that method like this:
throw callMethodThatAlwaysThrowsUncheckedExceptions();
And thus will help the compiler to see that this is the last statement of that execution branch.
This also works greatly with different exceptions, just return instead of throw
To indicate that you don't expect a line to be reachable (after your call to the throwing method) you can
throw new AssertionError("comment to your co-developers why this never gets reached")
I like minus's answer, but it can be a bit unreadable to users that might mistakenly think return result; will always be executed (regardless of the value of success).
As an alternative, you can change
void callMethodThatAlwaysThrowsUncheckedExceptions () {}
to
Object callMethodThatAlwaysThrowsUncheckedExceptions () {}
(no need to change the method body).
Now you can write
public Object someMethod() {
....
if (success) {
return result;
} else {
return callMethodThatAlwaysThrowsUncheckedExceptions();
}
}
None of the answers above matched my taste of programming. The closest match that I found is here. Inspired from this linked answer, I handled such missing return statement errors in the following way:
First making the return type of the method same as that of exception which it always throws
MyCustomRuntimeException callMethodThatAlwaysThrowsUncheckedExceptions() {
// ....
throw new MyCustomRuntimeException();
}
Next whenever we have to fail the method execution, simply call above method and throw it
public Object someMethod() {
// ....
if (success) {
return result;
} else {
throw callMethodThatAlwaysThrowsUncheckedExceptions();
}
}
This can be used even in methods having void return type without explicitly mentioning the throw keyword. Ofcourse in such places some IDEs may warn of UnusedReturnValue but that can be suppressed as well.
Recently I saw following piece of code on GitHub:
private static String safeToString(Object obj) {
if (obj == null) return null;
try {
return obj.toString();
} catch (Throwable t) {
return "Error occured";
}
}
I've never placed toString() method invocations inside the try-catch blocks. But now when I think about it, it might make sense. For example someone could overwrite toString() method in it's class that might throw a runtime exception, like NullPointerException. So we can try to catch Exception. But why Throwable? Do you think it makes any sense?
There is almost never a good reason to do this. The contract of toString() does not say it’s permissible to throw an exception from that method. Any code which throws an exception is broken code, and such an exception needs to be exposed and fixed, not suppressed.
In the case where you are converting some “bad” object from a library which is out of your control to a String, it might be appropriate to write catch (RuntimeExcepton e), but such a catch should be accompanied by comments which describe in detail why it is necessary, because under normal circumstances, it is not needed.
Rogue exception-throwing toString methods aside, note that Java already has at least two “safe” ways to convert a possibly null value to a String:
Objects.toString(obj, null)
String.valueOf(obj)
…so I would question whether the safeToString method should exist at all.
There are rare cases where you might want to catch an Error like this. In general it's a bad idea however, in this case it might make sense as this is generally for logging/debugging purposes and not used directly by the application.
I would prefer something more informative such as
private static String safeToString(Object obj) {
if (obj == null) return null;
try {
return obj.toString();
} catch (Throwable t) {
return obj.getClass() + ".toString() threw " + t;
}
}
e.g.
class Element {
Object data;
Element e;
public String toString() {
return data + (e == null ? "" : e.toString());
}
}
Element e = new Element();
e.data = "hi";
e.e = e; // oops
System.out.println("e: " + safeToString(e)); // doesn't kill the thread or JVM.
Throwable is the parent class of Exception and Error.
It is normally a bad idea to try and catch Error, as it is designed to not be caught.
Catching Throwable is just the overachieved and counterproductive version of catching Exception. Nonetheless, if for some reason you created another kind of Throwable you want to catch along with an Exception, that could be a way to do that in a single try/catch block. Not that it would be a clean way to do so, but it would work.
EDIT for the TL;DR : in most cases, catch Exception instead of Throwable.
It is incorrect to catch any Throwable and then continue execution since it includes Error, which is meant to be fatal:
From the Javadocs:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.
That is, some Errors can be recovered (e.g. LinkageError), but others not so much.
But catching Exception might be a valid use-case for example in logging code where you don't want the execution to break simply because a call to toString() fails:
private static String safeToString(Object obj) {
try {
return obj == null ? "null" : obj.toString();
} catch (Exception e) {
return "<exception: " + e + ">";
}
}
I'm a relative newbie to custom error handling in Java, and I'm trying to figure out how to use catch statements to deliver specific messages inside of an if statement. I wanted to get some extra sets of eyes to look at what I'm trying to do and offer feedback before I completely overthink this and overdo it too badly.
Consider:
We have a directory of hourly log files and I have an on-demand reporting job creates a concatenation of all today's log files created so far. I want to add a step that checks for the existence of a concatenated log file, deletes it then creates it if present, or just creates it if it's not present. With the code below, I'm returning an exception if, for some reason, the new file cannot be created.
try {
File file = new File (destinationPath + "todayToNowLogFile.csv");
if(file.exists())
{
if(file.delete())
{
System.out.println(file.getName() + " is deleted!");
} else {
System.out.println("Existing file cannot be deleted.")
}
} else {
System.out.println("File will be created.");
}
}
//
catch(Exception e) {
System.err.println("Exception: ");
System.out.println("Exception: "+ e.getMessage().getClass().getName());
e.printStackTrace();
}
Now, in the case where the file cannot be deleted, I would like to display the exception preventing file deletion. First, I would need to catch that error, but then where do I put the try?
Doing something like this...
try
{
if(file.delete())
{
System.out.println(file.getName() + " is deleted!");
}
}
else {
catch(Exception eDel) {
System.err.println("Exception: ");
System.out.println("Exception: "+ eDel.getMessage().getClass().getName());
eDel.printStackTrace();
}
}
....interrupts the if...then block. I'm not sure how to insert a try...catch within an if...then. Is there a way to do this? Or does my original code catch EVERY error associated with ANY operation on the file defined in the try block, and I would need to put if...then logic in the catch block, something along the lines of this pseudocode....
catch(Exception e) {
if(exception relates to file deletion) {
"File delete exception " + exceptionMessages;
} else if(exception relates to file creation) {
"File create exception " + exceptionMessages;
} else if(other exception) {
"other exception " + exceptionMessage;
} else {
"no exceptions encountered"
}
}
What's the most appropriate way to handle this type of situation?
You should think of try/catch as any other statement. So you can put it inside any of two branches of if/then/else statement, but it have to be whole inside:
if(statement){
...
try{
...
}catch(...){
...
}
...
}else{
...
try{
...
}catch(...){
...
}
...
}
If you have to catch multiple exceptions you can achieve this by multiple catch parts:
try{
...
}catch(Exception1 e1){
...
}catch(Exception2 e2){
...
}catch(Exception3 e3){
...
}
What you want here is to create your own Exception class.
To create an exception class say you need to extend Exception class. Here's an example.
Lets say my custom exception class should be named as MyFileErrorException
So I create a new class like this -
class MyFileErrorException extends Exception {
private String message = null;
public MyFileErrorException() {
super();
}
public MyFileErrorException(String message) {
super(message);
this.message = message;
}
public MyFileErrorException(Throwable cause) {
super(cause);
}
#Override
public String toString() {
return message;
}
#Override
public String getMessage() {
return message;
}
}
Now I need to throw this exception at will. So in Your case you wantto catch File delete exception so the code will like this -
if(file.delete())
{
System.out.println(file.getName() + " is deleted!");
} else {
try{
System.out.println("Existing file cannot be deleted.")
throw new MyFileErrorException("File Could not be deleted val is null");
}catch(MyFileErrorException ex){
//Do wahtever you want to do
}
}
At first you should check if any method could throw any specific Exceptions. You could do this by looking into the Javadoc or use your favorite IDE.
If you catch Exception as the Exception class, it catches every Exception that is subclass of it.
If you want to have specific Exception handling, e.g. for an IOException like in the delete() method, you can catch every specific Exceptionclass or use multi-catch in Java 7
try {
do regular code that can throw exceptions
} catch(Exception e) {
it catches every Exception that is a subclass of Exception.
You handle every exception raised in the try block above by the same way
}
If you want to handle exceptions in different ways, e.g. print different messages, just do this like the following example:
try {
do sth
} catch (SpecificExceptionclass sec) {
do sth specific for this exception
} catch (AnotherExceptionClass aec) {
do sth else
}
Or just use Multicatch in Java 7, if you want to have same exception handling for some specific exception classes:
try {
do sth
} catch (SpecificExceptionclass | AnotherExceptionClass e) {
do sth specific for this exception
}
To achieve different Exceptions thrown in your code the methods should at least throw different exceptions. In your example with file.exists() and file.delete() there's only an IOException thrown by your code, so there is no use of specific exception handling.
I think it would be a good idea to put your code in a function that returns true or false.
1: True means the file does not exist and was created
2: False means the file exists and was deleted.
3: An exception if the file exists but cant be deleted.
Also provide a separate function to determine if the file exists or not.
Your javadoc at the top of your functions should explain the above so the caller of your functions don't have to look at their content to determine how to use them.
Note an exception is an unusual event and shouldn't be thrown to indicate the state of inserting/deleting. It should be reserved for unusual conditions which the caller normally wouldn't encounter.
A note on exceptions: If you have a large project with 1000 classes each of which has on average 20 functions, that's 20000 functions. Its not practical to pepper each function with excessive exception handling (such as checking for nulls passed in as arguments). A solution to this is to handle checked exceptions in the java language (FileIO) and let (the bulk) of unchecked exceptions ripple up the function call chain until you leave all your business logic and are about to display the results. You only catch them if you want to add additional information to the exception before rethrowing it. Example: adding the primary key value of the record of an SQLExeption being thrown so you know what record is causing problems. Just before you return to the user, log the stack trace and display a simplified message to the user (not the stack trace). The caller of your function should read its javadoc to see how to use it. If he violates your javadoc, the function may or may not throw an exception. Its his reponsibility to follow the javadoc. Last point: your project should have general coding policies for the entire project to prevent some types of exceptions from accidently being introduced by the caller such as: all functions are not epected to recieve nulls as arguments or will return a null unless specified in its javadoc. All functions will accept as arguments (or return) empty lists or empty strings correctly unless specified in their javadoc.
Below is the class somebody else wrote.
The problem that I am facing is that when it get's into the parse method with null as the rawString, it is throwing NumberFormatException.
So what I was thinking to do is, I should catch that NumberFormatException and set the value itself as null. So the way I did is right?
public class ByteAttr {
#JExType(sequence = 1)
private Byte value;
public static ByteAttr parse(String rawString) {
ByteAttr attr = new ByteAttr();
try {
attr.setValue(Byte.valueOf(rawString));
} catch (NumberFormatException nfEx) {
attr.setValue(null);
}
return attr;
}
public Byte getValue() {
return this.value;
}
public void setValue(Byte value) {
this.value = value;
}
}
The correct approach depends on what you want to accomplish in the program.
If it makes sense for ByteAttr.getValue() to return null later in your program, then your approach could work.
However, you need to consider whether you should be throwing an exception if parse is called with an indecipherable argument (including null). An alternative is to catch the NumberFormatException and throw a different exception that has semantic meaning in your program.
public static ByteAttr parse(String rawString) throws BadAttributeException {
ByteAttr attr = new ByteAttr();
try {
attr.setValue(Byte.valueOf(rawString));
} catch (NumberFormatException nfEx) {
throw new BadAttributeException(nfEx); // wrap original exception
}
return attr;
}
Another technique is to pass a default value to parse for those cases when rawString is indecipherable:
public static ByteAttr parse(String rawString, Byte defaultValue) {
ByteAttr attr = new ByteAttr();
try {
attr.setValue(Byte.valueOf(rawString));
} catch (NumberFormatException nfEx) {
attr.setValue(default);
}
return attr;
}
You need to do four things:
Decide what an unparsable number string means in the context in which you will be using the method. Does it mean an internal problem in the program? A corrupt file? A user typo? Nothing wrong but that string needs to be handled differently?
Decide the best way to handle it, taking that into account. Almost always, if the error is triggered by external input you need to report it back. Substituting null may be a good way of handling it.
Document what you decide to do. If a method is going to return null with some specific meaning, that needs to be written down as comments, preferably Javadoc commments.
Implement your decision.
I get the impression, perhaps unfairly, that you have jumped straight to step 4, without thinking through the possible causes and proper reporting of the problem.
You can add an early exit with a condition like:
if (rawString != null) {
return attr; // or other value you prefer
}
You can also make sure the caller of the parse method test for null value and avoid calling parse when it is.
It depends on the tolerance to null values in your application. If you expect the users to not pass null string to the parse() method, then you should do a defensive null check and throw an exception.
if (null == rawString) {
throw new CustomException("rawString cannot be null");
}
The same would apply to the catch block for NumberFormatException, where instead of silently setting the value of Byte attribute to null, you should throw an exception with appropriate message.
But if null is perfectly acceptable, then you should perform a defensive null check and set the Byte attribute to null. The NumberFormatException should certainly be NOT suppressed, IMHO.
In java, Which of the following is the more "accepted" way of dealing with possibly null references? note that a null reference does not always indicate an error...
if (reference == null) {
//create new reference or whatever
}
else {
//do stuff here
}
or
try {
//do stuff here
}
catch (NullPointerException e) {
//create new reference or whatever
}
The answers already given are excellent (don't use exceptions for control flow; exceptions are expensive to throw and handle). There's one other important reason specifically not to catch NullPointerException.
Consider a code block that does the following:
try {
reference.someMethod();
// Some other code
}
catch (NullPointerException e) {
// 'reference' was null, right? Not so fast...
}
This might seem like a safe way to handle nullity of reference ...but what if reference was non-null and someMethod() raised NPE? Or what if there was a NPE raised elsewhere in the try block? Catching NPE is a surefire way to prevent bugs from being found and fixed.
Catching exceptions is relatively expensive. It's usually better to detect the condition rather than react to it.
Of course this one
if (reference == null) {
//create new reference or whatever
}
else {
//do stuff here
}
we shouldn't rely on exception for decision making, that aren't given for that purpose at all, also they are expensive.
Well If you aren't making decision and just verifying for initialized variable then
if (reference == null) {
//create new reference or whatever
}
//use this variable now safely
I have seen some auto code generator wraps up this thing in accessors/getter method.
I think in general an exception should be reserved for exceptional circumstances - if a null reference is sometimes expected, you should check for it and handle it explicitly.
From the answers its clear that catching an exception is not good. :)
Exceptions are definitely not free of cost. This might help you to understand it in depth. .
I would also like to mention an another practice while comparing your object with a known value.
This is the traditional way to do the job: (check whether the object is null or not and then compare)
Object obj = ??? //We dont know whether its null or not.
if(obj!=null && obj.equals(Constants.SOME_CONSTANT)){
//your logic
}
but in this way, you dont have to bother about your object:
Object obj = ???
if(Constants.SOME_CONSTANT.equals(obj)){ //this will never throw
//nullpointer as constant can not be null.
}
The first one, throwing exceptions is a costly operation.
The first form:
if (reference == null)
{
//create new reference or whatever
}
else
{
//do stuff here
}
You should not use exceptions for control flow.
Exceptions are for handling exceptional circumstances that would not normally occur during normal operating conditions.
You should use exception catching where you do not expect there to be an error. If something can be null, then you should check for that.
maybe the try catch approach will start making sense in this situation when we can start doing
try {
//do stuff here
}
catch (NullPointerException e) {
//create new reference or whatever
retry;
}
This is related to your style of development, if you are developing code using "safe" style you have to use
if(null == myInstance){
// some code
}else{
// some code
}
but if you do not use this style at least you should catch exception, but in this case it NullPointerException and I think preferably to check input parameters to null and not wait to throwing exception.
Since you asked for Best Practices, I want to point out that Martin Fowler suggests to introduce a subclass for null references as best practice.
public class NullCustomer extends Customer {}
Thus, you avoiding the hassle of dealing with NullPointerException's, which are unchecked. Methods which might return a Customer value of null, would then instead return a NullCustomer instead of null.
Your check would look like:
final Customer c = findCustomerById( id );
if ( c instanceof NullCustomer ) {
// customer not found, do something ...
} else {
// normal customer treatment
printCustomer( c );
}
In my opinion, it is permissible in some cases to catch a NullPointerException to avoid complex checks for null references and enhance code readability, e.g.
private void printCustomer( final Customer c ) {
try {
System.out.println( "Customer " + c.getSurname() + " " + c.getName() + "living in " + c.getAddress().getCity() + ", " + c.getAddress().getStreet() );
} catch ( NullPointerException ex ) {
System.err.println( "Unable to print out customer information.", ex );
}
An argument against it is that by checking for individual members being null, you can write a more detailed error message, but that is often not necessary.