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.
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.
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).
In Java 7, the feature was added to (via getSuppressed()) get exceptions thrown from the implicit finally block of a try-with-resources statement.
There still doesn't seem to be a way (that I know of) to do the opposite - when there is an explicit finally block and that throws an exception, masking the exceptions thrown and pending from the try/catch.
Why does Java not provide functionality to get these buried/lost exceptions through a mechanism similar to getSuppressed()?
It would seem that the implementation of this functionality would be similar to that used in getSuppressed() or chained exceptions, and the provided benefit would be very useful, yet it continues to be left out of each release.
What would be the danger of making these masked exceptions available to programmers through a method call similar to getSuppressed()?
(Apologies in advance if this functionality already exists and I'm just clueless.)
The suppression thing isn't limited to try-with-resources, and you can use it for similar situations yourself. E.g., it is provided for other situations.
try-with-resources puts the logic for closing the resources behind the scenes, so you don't have direct access in your own code to dealing with any exceptions that occur during the process. So they added the "suppression" thing so they could use it in that behind-the-scenes code.
But cleverly, they didn't only make it something that could be used there. You can use it yourself, via Throwable#addSuppressed.
You can see this in the pseudo-code example given in JLS §14.20.3.1; here's a real code version of it:
{
SomeResource someResource = null;
Throwable primaryException = null;
try {
someResource = /*...get the resource...*/;
/*...do something...*/
}
catch (Throwable t) {
primaryException = t;
throw t;
}
finally {
if (someResource != null) {
if (primaryException != null) {
// Dealing with a primary exception, close the resource
// and suppress any exception resulting
try {
someResource.close();
}
catch (Throwable suppressed) {
primaryException.addSuppressed(suppressed);
}
}
else {
// Not dealing with a primary exception, close the
// resource without suppressing any resulting exception
someResource.close();
}
}
}
}
Note the different behaviour (Using exception A for the exception in try, exception B in finally):
In a try-with-resources exception A suppresses exception B.
In a normal try exception B masks exception A.
If you want backwards compatibility (And you ALWAYS want it), you need to make B suppress A. But that is the complete opposite of what try-with-resources does (and actually, the opposite of what most developers want).
As a workaround, you can just use the (slightly modified) code that is in the Oracle blog on how try-with-resources works:
Exception ex;
try {
doWork();
} catch (Exception e) {
ex = e;
throw(e);
} finally {
try {
doFinally();
} catch (Exception e) {
if (ex != null) {
ex.addSuppressed(e);
} else {
throw(e);
}
}
}
Obviously move the throw out of the initial catch if you want the finally exception to suppress the initial one.
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.
Basically iterating through a list and,
- Invoke method on first object
- Catch the first exception (if any); if there are no more exceptions to catch, return normally. Otherwise, keep on invoking method until all exceptions are caught.
- Move on to next object.
I can iterate through each object, invoke the method, and catch one exception but I do not know how to continuously invoke the method on it and keep on catching exceptions.
This is similar to the other answers, but without the flag, which seems like clutter to me. I don't really understand the question though, so I'm just throwing it out there in case it is useful.
for (Item item : items) {
while (true) {
try {
item.doSomething();
break;
} catch (MyException ex) {
log.warn("Something failed.", ex);
}
}
}
This approach hinges on the operation of the unlabeled break statement, which completes abruptly and then exits the enclosing while statement normally.
Based on subsequent comments, I think there is some confusion about what it means when there are multiple exceptions declared to be thrown by a method.
Each invocation of a method can be terminated by just one exception being thrown. You can't somehow resume invocation where it left off, and handle subsequent exceptions.
So, if a method throws multiple exceptions, catch a common ancestor, and move on. For example, if a method throws java.io.EOFException or java.nio.channels.ClosedChannelException, you could simply catch java.io.IOException since it is a common ancestor. (You could also catch java.lang.Exception or java.lang.Throwable for the same reason.) Invoking the method again under the same conditions won't get you any further.
If you want to attempt to invoke the method on each object, even if some fail, use this:
for (Item item : items) {
try {
item.doSomething();
} catch (Exception ex) { /* This could be any common ancestor. */
log.warn("Something failed.", ex);
}
}
If you're talking about dealing with a single method call that will throw more than one exception, it can't be done -- no matter how many times you call the method, it will keep on throwing the first exception. You can't go back into the method and keep running from there; after throwing one exception, it's all over.
But if you're talking about a method that sometimes throws exceptions and sometimes doesn't, try something like this:
boolean thrown = false;
do {
try {
thrown = false;
method();
}
catch (Exception e) {
thrown = true;
// Handle as you like
}
} (while thrown);
This is what I understand.
You have an object's method which may throw a number of exceptions.
What you want to do is to catch them all and continue with the next object in the list.
Is that correct?
So, that would be:
for( YourObject o : yourList ) {
try {
o.thatMethod();//invoke that risky method
} catch( SomeExceptionClass sec ) {
// Do something with that exception
} catch( SomeOtherExceptionClass soec ) {
// Do something with that exception
} catch( YetAnotherxceptionClass yaec ) {
// Do something with that exception
} catch( OtherUnRelatedException oue ) {
// Do something with that exception
}
}
When you do this, if the invocation of thatMethod() throws an exception and that exception is listed in the catch section, the execution flow will jump to that exception and after it will continue to the normal flow ( which is the for loop and will continue with the next object )
I hope this is what to need. For more information read: The catch block in the Java Tutorial section Essential classes
I'm assuming that you are trying to performs some kind of validation to the items in a list, where the validation errors are reported by throwing exceptions. I'm also assuming that you are trying to collect all of the validation errors.
The simple answer is that this problem cannot be solved using this approach. To understand why, take a look at this:
boolean exceptionCaught = false;
do {
try {
item.doSomething();
} catch (MyException e) {
exceptionCaught = true;
}
} while (exceptionCaught);
This fails because each time you call item.doSomething() it is going to throw an exception at exactly the same place. The net result is an infinite loop.
The best you can do with this approach is to capture the first exception for each item in the list.
So how can you achieve what you are trying to achieve? The answer is that you have to change the validation code to use some other way to report errors than throwing exceptions. For example, you could change:
class Item {
...
void validate() {
if (noHat) {
throw new MyException("bad hat");
}
if (noPants) {
throw new MyException("world-wide pants");
}
}
}
to something like this:
class Item {
...
void isValid(List<MyException> errors) {
boolean ok = true;
if (noHat) {
errors.add(new MyException("bad hat"));
ok = false;
}
if (noPants) {
errors.add(new MyException("world-wide pants"));
ok = false;
}
return ok;
}
}
Messy huh! You could sugar this in various ways, but this style of error reporting is always going to be more complicated. But I don't think there is a practical way to avoid the messiness AND capture ALL of the validation errors.