Taking the nusances out of AutoCloseable - java

Up front: I'm a C# guy doing Java right now. Some of these frustrations come from my lack of knowledge of Java.
First, is there a way to have a "safe" AutoCloseable implementation that does not require the Exception to be checked? If I'm implmementing my own class that won't throw from its close method, I don't see why I have to check it.
Second, is there a way to simplify the expression in the try statement where I don't care what's returned? For instance in C# I can do this:
using (new Disposable())
{
// yay!
}
and Java seems to force me to assign it to a temporary variable:
try (AutoCloseable iDontCare = getAutoCloseable()) {
// dont you dare use iDontCare
}
I wish I could simplify the Java to
try (getAutoCloseable()) {
// yay!
}

C# isn't quite Java; this is one of those gotchas you'll have to deal with going forward.
First, is there a way to have a "safe" AutoCloseable implementation that does not require the Exception to be checked? If I'm implmementing my own class that won't throw from its close method, I don't see why I have to check it.
You have to because it's mandated by the interface. Not just that, but it throws a checked exception, which does have to be handled at some level.
If you know for a fact that your code will never throw any kind of exception, you could still place the throwing of the exception in some kind of guaranteed-not-to-be-executed-block inside of your implemented close method. Or, implement your own interface which extends AutoCloseable and overrides close to not throw an exception.

Your first question:
Yes. You can implement AutoCloseable.close without the throws Exception part if your implementation doesn't throw checked exceptions.
Your second question:
No. The try with resources statement requires that variable. You can rename it to something like ignored or unused to make that clear.
final class Test implements AutoCloseable {
#Override
public void close() {
System.out.println("Closing");
}
public static void main(String[] args) {
try (Test ignored = new Test()) {
System.out.println("Not using ignored");
}
}
}

Makoto's answer does a nice job of addressing the first part of your question, so I'll attempt to address the second.
I think what you want is a try (without resources). For example:
try {
//yay!
} finally {
// always executed
}
The finally block will execute regardless of whether an exception is thrown or not.
Edit:
If you don't need anything to execute, you could just declare a new block
{
//yay!
}

Related

Can we create and use our own interface instead of defined by the java?

Q1 : (removed)
Q2 : try-with-resource to create own resource implement AutoCloseable interface and override close() method.
From javadoc
Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
So, here I created a simple program MyAuto.java
class Demo implements AutoCloseable {
public void show() {
System.out.println("show");
}
public void close() {
System.out.println("close from demo");
}
}
class MyAuto {
public static void main(String[] args) {
try(Demo d = new Demo()) {
int x = 10/0;
d.show();
}catch(ArithmeticException e) {
System.out.println(e);
}
}
}
This program runs fine. :) and giving output
close from demo : as expected, no matters exception occurs, d will be closed.
But my question is I didn't write any code that close this resource, I simply put a print statement. What here actually closing a resource mean ? Assigning null to reference variable of resource or anything else ?
Or JVM runs any other method after running close() behind the scene.
And finally the most important question..
Q3 : In the above scenario if I add my own interface AutoCloseable
interface AutoCloseable {
void close() throws Exception;
}
It gives compile time error on compiling MyAuto.java
error: incompatible types: try-with-resources not applicable to variable type
try(Demo d = new Demo()) {
^
(Demo cannot be converted to AutoCloseable).
So, please give me answer why it's happening. Why can't we create and use our own Interfaces instead of provided by java. What is difference between my interface and the one predefined, although both are same.
What is difference between my interface and the one predefined, although both are same.
They're not the same. Not by a long shot.
The AutoCloseable required for try-with-resources is java.lang.AutoCloseable. Your custom AutoCloseable doesn't come from that package, so Java isn't going to respect it.
Above all, introducing that would not be the best approach, since it'll only lead to confusing semantics and a bad experience later down the road, even if you elected to have your interface extend java.lang.AutoCloseable for whatever reason.
In the same vein...
...I didn't write any code that close this resource, I simply put a print statement. What here actually closing a resource mean ? Assigning null to reference variable of resource or anything else ? Or JVM runs any other method after running close() behind the scene.
The interface can't enforce anything like that. All it can do is provide a mechanism that, if well-implemented, will behave as you expect.

Is it okay to declare a checked exception for an exception thrown by a called method?

Consider this:
public void Do() throws Exception {
if (blah) throw new Exception(...);
Thingy thingy = ...;
Foo(thingy);
}
public void Foo(Thingy thingy) throws EmptyThingyException {
if (thingy == null ||
thingy.isEmpty()) throw new EmptyThingyException();
...
}
public class EmptyThingyException extends Throwable { ... }
In this case, is it okay to not handle EmptyThingyException inside Do and declare Do like so:
public void Do() throws Exception, EmptyThingyException {
or do I have to handle EmptyThingyException inside Do and throw it back again like so:
public void Do() throws Exception, EmptyThingyException {
try {
} catch (EmptyThingyException empty) {
throw empty;
}
...
}
The short answer to the question is:
Yes, it's correct to declare a checked exception thrown by a called method.
How a method achieves its purpose is an implementation detail and it shouldn't matter to the interface how much it does directly or how much it delegates to methods. The language rules about checked exceptions are carefully defined to make sure methods advertise all checked exceptions they may throw or methods they call throw (but are not handled by the method itself). Letting an unhandled exception get 'thrown through' a method is how things are supposed to work.
Indeed the answer is in the name of the construct "non-local exception handling" it was conceived to take effort out of endless error handling all the way up a call chain when the only real action is "that didn't work" at some point near the start.
To align to that method, you should only catch exceptions you're going to do something about.
Clean up code should be achieved with finally so the normal reasons to catch an exception are to log it and/or abandon a task at some point rather than letting the stack unwind further.
In this specific case the best answer would be to throw an IllegalArgumentException:
throw new IllegalArgumentException("thingy==null || thingy.isEmpty()");
That's unchecked and wisely so. Correct code shouldn't encounter illegal arguments and they should expect to be thrown rarely and be indicative of program flaw (either in the class, it's package or consumer code). External and user input should be validated directly and programs shouldn't rely on IllegalArgumentException.
In practice IllegalArgumentException and IllegalStateException should cover 'internal errors' meaning "You can't do this with that" or "You can't do that right now" respectively and should be commented to specify the fault.
The idea that you might sub-class those two because consumer code might respond differently to different illegal actions it might take is bodging pure and simple.
Program correctness includes that a program never makes an illegal call on some other part of the program or enters an invalid or corrupted state and exceptions only occur as a result of environmental failures that mean a program or sub-task in a program cannot be completed as intended.
if you want to do something after exception happen, then use try-catch, or you can just declare it on the method.
Beyond that, if EmptyThingyException is sub class of Exception, then it is no need to declare EmptyThingyException when you have declared Exception.
1- Declare the specific checked exceptions that your method can throw
public void foo() throws Exception { //Incorrect way
}
Always avoid doing this as in above code sample. It simply defeats the whole purpose of having checked exception. Declare the specific checked exceptions that your method can throw. If there are just too many such checked exceptions, you should probably wrap them in your own exception and add information to in exception message. You can also consider code refactoring also if possible.
2- Always catch only those exceptions that you can actually handle
catch (NoSuchMethodException e) {
throw e; //Avoid this as it doesn't help anything
}
Well this is most important concept. Don’t catch any exception just for the sake of catching it. Catch any exception only if you want to handle it or, you want to provide additional contextual information in that exception. If you can’t handle it in catch block, then best advice is just don’t catch it only to re-throw it.
3- Avoid using Throwable class
Throwable is the superclass of Exception and Error, as far as I know you need to use Throwable when you want to deal with both exceptions and errors, but it's definitely not your concern here, most of the java code deal with Exception and it's the way to go whenever you need to deal with checked exceptions http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html.
**
Well if I was you I would do something like :
public void Do() throws BlahIsFoundException{
try {
if (blah) throw new BlahIsFoundException(...);
Thingy thingy = ...;
Foo(thingy);
} catch(EmptyThingyException exception) {
//Handle the exception correctly, at least log it
} finally {
//Do some clean up if needed, for example close a database connection or free some resources.
}
}
public void Foo(Thingy thingy) throws EmptyThingyException {
if (thingy == null ||
thingy.isEmpty()) throw new EmptyThingyException();
...
}
public class EmptyThingyException extends Exception { ... }
public class BlahIsFoundException extends Exception { ... }
Hope that helps, here are some good documents to read :
http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
http://howtodoinjava.com/best-practices/java-exception-handling-best-practices

Good Practice : Exception Handling

I have 2 classes in my module where one of the class say Class A has methods which could throw InterruptedException, NoSuchElementException and another class say class B has methods which calls the method from class A.
Could someone please guide me with what is a good practice to implement exception handling? Shall it be CASE 1 or CASE 2 or any other way to do so.
CASE 1 ::
Class A
methodA1 throws InterruptedException, NoSuchElementException {...}
methodA2 throws InterruptedException, NoSuchElementException {...}
.
.
.
.
methodA10 throws InterruptedException, NoSuchElementException {...}
Class B
a = new A();
methodB1 {
try{
a.methodA1();
a.methodA2();
}
catch(InterruptedException){
//do something
}
catch(NoSuchElementException){
//do something else
}
}
methodB2 {
try{
a.methodA9();
a.methodA10();
}
catch(InterruptedException){
//do something
}
catch(NoSuchElementException){
//do something else
}
}
SCENARIO 2 ::
Class A
methodA1 {
try{
//perform actions
}
catch(InterruptedException){
//do something
}
catch(NoSuchElementException){
//do something else
}
}
.
.
.
.
methodA10 {
try{
//perform actions
}
catch(InterruptedException){
//do something
}
catch(NoSuchElementException){
//do something else
}
}
Class B
a = new A();
methodB1 {
a.methodA1();
a.methodA2();
}
methodB2 {
a.methodA1();
a.methodA2();
}
It really depends on what you need to achieve.
The situation might be flexible enough to allow you to handle exceptions as they arise within the specific module. For instance, you have some process which queues elements, an exception is thrown and in your exception handling code, you simply try again. The caller knows that when the method is called, something will be added but does not require to be informed of when/how.
On the other hand, the situation might require that you inform the caller immediately should something happen. Taking the above example, maybe the caller would need to know if the queueing was successful or not so that they could direct the user accordingly.
There are also scenarios where bubbling up the exception, although recommended, needs to be done in such a way that internal exceptions are not divulged to the caller since it could expose the internal structure of the module, which could be a security risk.
Usually, what one does is that, where necessary, exceptions are wrapped within custom exceptions. And if any errors occur, the custom exceptions are used to bubble up the error. It will then be up to the caller to decide what to do if/when an error occurs.
rethrowing or handling depends whether the caller can handle the exception reasonably.
E.g. if an UI triggers a calculation via a method chain, it might not be reasonable that somewhere in this chain the exception gets lost, as it would be of interest to present in the ui the exception to the user.
So it mostly depends on the context which scenario is preferable.
A rule of thumb is: However can handle the exception reasonably should do so
It depends on what you want to achieve by that and where you want to handle the exceptions. If you can handle the exception properly inside the methodA1() it'll be easier to use the method (no try-catch necessary around method calls)
If you can't handle the exception in the method itself (e.g. not enough information to handle the exception properly) and you can only handle it properly in methodB1 then you should use SCENARIO 2

Should Closeable be used as the Java equivalent for .NET's IDisposable?

Update: As #PaulGroke points out below, things have changed with Java 7: there now is AutoCloseable. Which isn't tied to streams and supported by the new try-with-resources construct.
AutoCloseable is the direct Java equivalent for .NET's IDisposable interface.
The Closeable interface introduced in Java 1.5 is tightly tied to streams, and even has an exception specifier for IOException. This suggests that it should only be used for streams or other IO related activities, rather than general purpose cleanup logic.
Certainly the description for the close() method would make absolutely no sense outside of a stream/IO context:
void close() throws IOException
Closes this stream and releases any system resources associated with it.
Should I therefore declare my own interface, Disposable, with a Dispose() method on it, and use that as an analogue to .NET's IDisposable interface? Or should I re-use Closeable even though it may not be a perfect fit?
I'm sure most people are aware of it, but since this question is still among the top results when searching for "IDisposable Java" (#2 result for me just now), and it's still not mentioned here...
Things have changed with Java 7: there now is AutoCloseable. Which isn't tied to streams and supported by the new try-with-resources construct.
Especially given that close() throws an IOException you then have to write exception handling code for, I would advise you write your own interface. This interface can then throw any checked exceptions that are appropriate to the use you want to put the interface to.
Interfaces tend to signify intent in the mind of the reader, so having a class implement an IO-associated Closeable interface will make the reader assume the class is also IO-based.
Obviously, if the objects you do want to close are all IO-related, you should use Closeable. But otherwise go for
/** Interface for objects that require cleanup post-use. Call dispose() in finally block! */
public interface Disposable {
public void dispose();
}
When implementing Closeable (or AutoClosable for that matter) in a class it's also possible to just omit the throws declaration:
class X implements Closeable {
#Override public void close() /* I don't throw */ {
}
}
So when someone is using a typed object they can call close() without having to catch anything:
void f() { // notice no need for throws because close() doesn't throw
X x = new X();
try {
// do something
} finally {
x.close();
}
}
It is also compatible with anything expecting a Closeable: if this object is passed into somewhere that handles Closeable, they already anticipate an exception and handle it correctly, albeit futilely in this case.
This includes libraries like Guava Closeables and Java 7 try-with-resources as Paul Groke suggests:
try (X x = new X()) {
// do something
}
There's a rare caveat though: you can't reintroduce the exception in child-classes once it's stripped:
class Y extends X {
/* compile error */
#Override public void close() throws IOException {
// Y.close clashes with X.close: overridden method does not throw IOException
}
}

Why is call to static method in Java not being made?

I have a fairly standard creational pattern whereby a class exposes a static method for returning instances of itself, like so:
public class MyClass {
private MyClass(/*parameter list*/) {
// internal construction
}
public static MyClass GetMyClass(/*parameter list*/) {
return new MyClass(/*parameter list*/);
}
}
...
//this line wont break in the debugger and seemingly never gets called - why?
MyClass inst = MyClass.GetMyClass(/*parameter list*/);
However, inst is always null. I can't break on the line that calls the static method, the debugger just ignores it - what's going on?
Edit: Thanks for the suggestions.
All projects have been cleaned and rebuilt (manully in NetBeans)
I have added a break in the static method and no it isn't hit.
Yes, the code above is being called (ultimately) in a constructor for a Swing 'FrameView' though it surely shouldn't matter where I am calling this from, should it?
There is no exception swallowing anywhere
Side note, other than the missing class declaration (which was a typo) why is this not valid Java? Why is this obviously C# code? Explanations would be more helpful than downvotes :)
Edit II: The Params is just supposed to indicate a whole load of parameters - sorry if this confused anyone, I obviously know parameters have type declarations and so on, the code above was intended as a quick shorthand version rather than a full and (complicated) real sample...
A couple of options:
An exception is being thrown which you're somehow missing
You're not debugging the code that you think you are (i.e. your built code is out of date with your source code)
The latter is the most likely one, IMO.
Apparently you're swallowing an exception inside the constructor something like:
try {
// Something.
} catch (Exception e) {
}
You should never do that. It makes debugging and nailing down the root cause much harder. Rather throw it or at least do a e.printStackTrace(). If throwing and you don't want to use the throws clause for some reasons, consider using a RuntimeException (or one of its subclasses). E.g.
try {
// Something.
} catch (Exception e) {
throw new RuntimeException("Construction failed.", e); // Try to be more specific, e.g. IllegalArgumentException or so. Or just write robust code, i.e. nullchecks and so on.
}
or (but in my opinion not very applicable in your case):
try {
// Something.
} catch (Exception e) {
e.printStackTrace();
}
I understand that you are trying to make a simple example to show your problem, however if you add the appropriate type statements into your sample code, then it both compiles and does what you expect.
However, in your original codebase you could simply place the breakpoint in the static method to see whether or not it is called.
Maybe a simple question, but you never know… are you sure that you are running the code that you think you are running? That is, is everything recompiled and built from the latest sources?
There is nothing wrong with :
MyClass inst = MyClass.GetMyClass(Params);
It depends what is before or after that line of code.
Start by doing this:
public class MyClass
{
private MyClass(/*parameter list*/)
{
System.out.println("entering MyClass(...)");
// internal construction
System.out.println("leaving MyClass(...)");
}
// Java uses lower case for method names - so get not Get
public static MyClass getMyClass(/*parameter list*/)
{
final MyClass foo;
System.out.println("entering getMyClass(...)");
foo = new MyClass(...);
System.out.println("leaving getMyClass(...)");
return (foo);
}
}
...
MyClass inst = MyClass.getMyClass(/*parameter list*/);
See if outside the debugger the code gets called.
If you are catching any exceptions, at the very least do:
catch(final WhateverException ex)
{
// at the very least do this so you can see that the exception happens
ex.printStackTrace();
}
Avoid catching Throwable, Error, Exception, and RuntimeException. Infact the best way do do it is get rid of all the catch statements and then only add catches for what the compiler tells you that you have to have.
The other thing is you do not say where MyClass inst = MyClass.getMyClass(/parameter list/); is called from. It is entirely possible that that line never gets hit.
You mention that you're calling this from the constructor of a FrameView, but I assume you're talking about an implementation or extension of that interface/object. My reasoning was to make sure you wern't recursively invoking the constructor.
I think the reason why catching java.lang.Exception isn't catching the problem is because it is likely too specific in this case. Try catching java.lang.Throwable which will catch errors like java.lang.NoClassDefFoundError - that frequently crops up when you have a jar missing somewhere.

Categories

Resources