What is the correct way of using return in the following method?
public Image getImage() {
try {
Image img = ImageIO.read(new File(URL));
return img;
} catch (IOException e) {
e.printStackTrace();
}
}
IDE asks me to return something at the end. But I don't know what I'm supposed to return.
The correct answer is: depends on your requirements. Options are:
If the caller of this method could deal with a null answer, return null from the catch block. Alternatively, you could return a "special" pre-defined image object in that case. Might be a slightly better way - as returning null is always the first step to cause Nullpointerexceptions elsewhere.
Or, you catch and rethrow some unchecked exception. Or you don't catch at all and you add "throws IoException" to the signature of the method.
When you are using Java 8, the simple solution is to use the new class Optional.
If your method catches the exception and doesn't throw anything, it must return some default value (perhaps null) after the try-catch block.
I think you shouldn't catch the exception. This way you only return a value if the ImageIO.read operation doesn't throw an exception. Of course you'll have to declare that your method throws IOException, since that's a checked exception.
This will force the caller of your method to handle IOException (or let its own caller handle it).
Related
I am trying to handle an exception 2 times
The first is in the core of a defined method :
Class Class1 {
public int method (int a, String b) {
try {
System.out.println(a+" "+b.length());
}
catch (NullPointerException e) {
// TODO: handle exception
System.out.println("catch from the method");
}
finally {
System.out.println("finally from the method");
}
return 0;
}
}
and the second
is when I call this method in main and passing a null parameter to it :
public Class Class2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Class1 c = null;
try {
c = new Class1();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
c.method(1, null);
}
catch (Exception e) {
// TODO: handle exception
System.out.println("catch from the main");
}
finally {
System.out.println("finally from the main");
}
System.out.println("\nEnd of the main");
}
}
and the result is :
catch from the method
finally from the method
finally from the main
End of the main
And now my question is, why the catch block in the main was not executed?
Once you catch an Exception, it doesn't go any further, but you can throw it again. If you want your main to also see the exception you need to throw the exception again after it is caught. Try this:
public int method (int a, String b) throws NullPointerException{
try {
System.out.println(a+" "+b.length());
}
catch (NullPointerException e) {
// TODO: handle exception
System.out.println("catch from the method");
throw e;
}
finally {
System.out.println("finally from the method");
}
return 0;
}
Notice since there is a throw in the function now, you need to include it in the function definition
Edit: As stated by a couple of people, NullPointerException does not really need to be caught because it is an unchecked exception. This is because it is a subclass of RuntimeException.
You find many texts on the mechanics of throwing and catching exceptions. What I find more important is how to make best use of the exceptions concept.
This is not exactly an answer to your question, but maybe clarifies some concepts behind the situation at hand.
Rules of Thumb
If a method fulfilled its job, it should return normally. If it failed to do so, it should throw an exception instead of the normal return. The exception coming out of your method should contain information on the problem (most of the standard exceptions already do that quite well).
In a subordinate method, you normally shouldn't use try/catch. If something goes wrong (some exception arises inside your method), then your method typically can't complete its job, it should tell its caller by means of an exception, and the easiest way is to just let the exception ripple through.
In a top-level method (e.g. main, main-menu action, button-click action), catch all exceptions, inform the user (and maybe the administrator) and continue (if possible/appropriate).
If your method gets one exception (e.g. a NullPointerException) and wants to show a different one to its caller, catch the exception, create the desired new one, using the original one as cause, and throw this new exception. Personally, I try to avoid this "exceptions translation" as much as possible.
Use finally if you have to close some resource that you obtained inside the body, that would stay blocked for extended periods of time if not closed. Think of I/O streams, database connections/transactions and similar things. Don't do it just for memory allocation, that's the garbage collector's job.
If you follow these rules, you'll find that your code can concentrate on its main job, isn't cluttered with lots of error handling, and still is robust in case of exceptions.
Your Example
It all depends on the question "What's the job of Class1.method()?".
That might be "Print these two numbers". Then, when it gets the NullPointerException, it won't fulfill its job, so it shouldn't return normally, and instead exit with an exception, most easily by doing nothing (no try/catch at all) and just letting the exceptions framework do its automatic job. That will mean that its caller gets the original NullPointerException:
public int method (int a, String b) {
System.out.println(a+" "+b.length());
}
If the job of Class1.method() were "Print these two numbers, but only if there is a string", then you should catch the NullPointerException inside (or better, check with an if) and return normally ("I've done my job!"). Then Class2.main() should be satisfied with the non-printing in case of null, and have no reason to do any error handling after calling Class1.method(). If Class2.main() doesn't want that behaviour, it shouldn't call Class1.method() in that case.
I have to work with lambda expressions. In this case the try block have create a JSON Object with the input strings. But I must implement that, if the creation doesn't work, it should return an Optional.Empty() instead of null.
How can I do that ?
In the current situation, the workflow stops, till the catch happens. So the other strings are ignored.
private Optional<JSONObject> testFile (Optional<String> jsonFileContent)
{
try
{
return jsonFileContent.map(fileContent -> new JSONObject(jsonFileContent)); // this lambda expression needs to be extended
}
catch(Exception e)
{
return null;
}
}
That is not a good way to handle errors, because:
If something goes wrong, neither you nor anyone who calls your code will have any idea why the operation failed.
What will you tell end users? “Something went wrong but we have no idea what, so you can’t do anything about it, and don’t bother trying to tell us either”?
If you aren’t sure of the best way to deal with an exception, don’t catch it at all. Instead, declare your method to throw it, and let a caller who is prepared to handle it deal with the exception. For example, a user interface might catch the exception and provide some of its details to the end user.
private Optional<JSONObject> testFile(Optional<String> jsonFileContent)
throws JSONException
{
if (jsonFileContent.isPresent())
{
return Optional.of(new JSONObject(jsonFileContent.get()));
}
else
{
return Optional.empty();
}
}
A note about catching exceptions:
Most classes which descend from RuntimeException in Java SE are meant to indicate programmer errors. Examples would be:
NullPointerException
IndexOutOfBoundsException
IllegalArgumentException
When these occur, they indicate your program logic is broken. You are not supposed to recover from them; you are supposed to notice them and fix the code responsible. Catching them and suppressing them will not make your program work.
Such exceptions should never be caught. This also means you should never write catch (Exception …) or catch (RuntimeException …). If you must write a catch block, catch only the exceptions you absolutely need to catch.
But the better option is simply not to catch anything and declare your method with throws JSONException.
private Optional<JSONObject> testFile (Optional<String> jsonFileContent)
{
try{
return jsonFileContent.map(fileContent -> a(fileContent));
}
catch(Exceptione)
{
return null;
}
Optional a(Optional<String> jsonFileContent) {
try{
return new JSONObject(jsonFileContent); // this lambda expression needs to be extended
} catch (Exception e) {
return Optional.empty();
}
}
You can write a method which would create a
new JSONObject(jsonFileContent).
And you will wrap the logic in your method in try with catch and will return null if an exception occurred.
Actually then after you invoked map you can do filter and then findFirst which is null and as findFirst returns Optional it
will return an empty Optional as you wanted.
Is this syntax best method?
method 1:
input
method2():
method2: (input)
try
catch
return(method1())
method3: (input)
....
This is so when an exception is thrown you rarely want the program to crash, so it's best to have a return statement so the user can declare a new input for the variable. I am reading my textbook for class and they don't cover a return. Otherwise, without the return, having a try-catch seems pointless if the program just terminates.
Your syntax is simply vulnerable bacaues it can easily go stackoverflow by a malicious user's repeated inputs that cause the exception in method2.
How about this:
method 1:
while
input
try
return method2(input)
catch
method2: (input)
return (some result)
method3: (input)
....
If a piece of code is in an authorative position to know exactly what to do with an exception, it can catch it and do whatever that is.
If it's not, it should throw it up to allow a higher level piece of code handle it. Sometimes it necessary to wrap such an exception in order to keep things at the same level of abstraction as the method call.
At the top level, when there is an exception no code can handle, it's up to a person to deal with it. You log the exception and apologize to the user.
The exception can be caught in the calling code.
Say you're reading a file in a method
Data readFile(String filename) {
try {
// Open file here
} catch (Exception e) {
// something has happened but you caught it here itself.
// Caller of this method may not know that.
}
}
Instead if your method throws an exception (Predefined or your custom):
Data readFile(String filename) throws FileNotFoundException {
// Open file here. If file name wrong, it throws a FileNotFoundException
}
This time the calling code knows that the method may throw an exception and thus, handle it the way it wants.
for e.g.
Data data = null;
while(data == null) {
try {
String f = /*Some code to read a string from input*/;
data = readFile(f);
} catch(Exception e) {
System.out.println("Unable to read. " + e);
}
}
Ofcourse, there are other ways to do it.
I have a design level doubt regarding creating APIs in Java. Suppose I have a class as follows :-
class Test
{
public final static String DEFAULT_ENCODING = "utf-8";
public byte[] encodeIt(String input)
{
try {
return input.getBytes(DEFAULT_ENCODING);
} catch(UnsupportedEncodingException e) {
// do something
}
}
}
I know that the UnsupportedEncodingException would never arise as I'm using a static string as the input to toBytes. It doesn't make sense to have encodeIt do a throws UnsupportedEncodingException because I dont wish the API users to expect and catch that error either.
In such cases, is the best practice to have an empty catch block?
It is a bad idea to have empty catch blocks. Even though your reasoning seems correct this design will at some stage cause you endless debugging and searching once exceptions do start happening and your code is swallowing them. I would wrap your exception in a RuntimeException here and throw that. Like so:
public encodeIt(String input)
{
try {
return input.getBytes(DEFAULT_ENCODING);
catch(UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
This way your exception will not stay hidden might it occur nor do your API users have to cater for it.
I do something like this:
public byte[] encodeIt(String input) {
try {
return input.getBytes(DEFAULT_ENCODING);
}
catch (UnsupportedEncodingException e) {
throw new ShouldNeverHappenException(e);
// or: throw new IllegalStateException(e);
}
}
(where ShouldNeverHappenException is a runtime exception, of course).
This way, if someone happens to change the constant value, or add an encoding argument, the method will fail fast and the problem will not go unnoticed or buried in log files.
In such cases, is the best practice to have an empty catch block?
I don't feel that's a good idea, ever. Empty catch blocks mean that something could happen and you'll never know.
Don't throw this exception. Catch it and log it so you can check your assumption that it can never happen, but at least you'll know if never arrives.
I usually follow the strategies outlined by other answers to this question (like soften the checked exception to RuntimeException). However, one interesting alternative is to use an assertion:
public byte[] encodeIt(String input)
{
try {
return input.getBytes(DEFAULT_ENCODING);
} catch(UnsupportedEncodingException e) {
assert false;
return null;
}
}
When assertions are enabled with the -ea JVM flag, this method would throw an AssertionError if ever UnsupportedEncodingException were thrown. An annoyance is the need to return a value (such as null), otherwise the code won't compile.
So perhaps the following is "nicer":
public byte[] encodeIt(String input)
{
try {
return input.getBytes(DEFAULT_ENCODING);
} catch(UnsupportedEncodingException e) {
throw new AssertionError("Unexpected.", e);
}
}
Not so materially different than throwing RuntimeException except that AssertionError is nicely self-documenting. And, being a subclass of Error, it represents a more fundamental failure than Exception normally implies. No chance for a catch (Exception e) clause somewhere higher up on the stack handling this thing (were it to ever occur).
The best way I think is to avoid checked exception. Just use an unchecked one. Then you will take the best of 2 worlds: you do will signal the error if it really happens and you won't force the user of your API to handle the exception.
If you are very, very sure that it would never happen, leave an empty catch block.
But for practice, just in case you change the code later on, it is better to log it to the console when the exception happens.
I've got a strange problem with a try/catch block I'm using. I've got this method, which just gets some data from a remote service and stores it.
public WFSGetCapabilitiesResponse wfsGetCapabilities(String url) {
WFSGetCapabilitiesResponse response = new WFSGetCapabilitiesResponse();
try {
WFSDataStore data = loadWFSCapabilities(url);
String[] typeNames = data.getTypeNames();
ArrayList<WFSFeatureTypeBase> wfsLayers = new ArrayList<WFSFeatureTypeBase>();
for (int i = 0; i < typeNames.length; i++) {
String typeName = typeNames[i];
WFSFeatureTypeBase newLayer = new WFSFeatureTypeBase();
newLayer.setTypeName(typeName);
newLayer.setName(typeName.split(":")[1]);
newLayer.setTitle(data.getFeatureTypeTitle(typeName));
newLayer.setAbstract(data.getFeatureTypeAbstract(typeName));
newLayer.setServiceUrl(url.split("\\?")[0]);
wfsLayers.add(newLayer);
}
response.setWFSLayers(wfsLayers);
} catch (IOException e) {
response.setError(WCSCapabilitiesResponse.IO_EXCEPTION);
response.setErrorMessage(e.getMessage());
response.setSuccessful(false);
e.printStackTrace();
return response;
}
return response;
}
If I run with this code, I get a null pointer exception ('data' is null, but don't really know if it's relevant). However, if I remove the return statement from my catch block everything is fine.
The strange thing is, the IOException is not being caught in either case, so I can't see why it's having such an impact.
So again, with the return in the catch block it doesn't work, without it it does... I really can't see why this would happen.
Any ideas?
Well, my first thought is that the catch block can only make a difference if an IOException is thrown - so we know for sure that that's happening. And likewise we know that without the catch block, this exception will propagate out of the wfsGetCapabilities method (presumably you added an appropriate throws declaration when you removed the catch block).
So chances are, in the "working" case, the calling code is catching the IOException higher up and handling it in such a way that your method appears to work judging by the output. Of course your method didn't work, and threw an exception, but perhaps there's a default fallback (or similar) which is invoked in an error case?
So that's the "strange" part hopefully dealt with. As for the "problem" part, if you're getting a NullPointerException thrown with the catch block, but not without it, it's clear that your catch block logic is not quite right and is causing this problem. From what you've posted it doesn't look like any of those immediate references would be null - take a look at the stack trace and determine from which line the exception is thrown, then fix it as you would any other NPE.