Is there any good way of using try-with-resources when opening an InputStream
in a constructor and then passing that to a super constructor?
Basically what I want to do is this:
public class A { public A(InputStream stream) { // Do something with the stream but don't close it since we didn't open it } } public class B { public B(File file) { // We open the stream so we need to ensure it's properly closed try (FileInputStream stream = new FileInputStream(file)) { super(new FileInputStream(file)); } } }
But, of course, since super
must be the first statement in the constructor this isn't allowed. Is there any good way of achieving this?
Note: A try -with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try -with-resources statement, any catch or finally block is run after the resources declared have been closed.
In Java, the Try-with-resources statement is a try statement that declares one or more resources in it. A resource is an object that must be closed once your program is done using it. For example, a File resource or a Socket connection resource.
If the exception throws from both try and finally blocks, the exception from try block will be suppressed with try-and-catch. On the other hand, if you use the try-with-resources statement, the exception from finally block (auto close throws exception) will be suppressed.
A resource is an object to be closed at the end of the program. As seen from the above syntax, we declare the try-with-resources statement by, declaring and instantiating the resource within the try clause. specifying and handling all exceptions that might be thrown while closing the resource.
Consider using a static factory method instead of using the constructor directly. Make at least B
's constructor private, and create a method such as
private B(InputStream is) { super(is); // Whatever else is needed } public static B newInstance(File file) { B result; try (FileInputStream stream = new FileInputStream(file)) { result = new B(stream); } // Further processing return result; }
Another way to go :
public class A { protected A(){ // so he can't be called from the outside, subclass ensure that init is done properly. } public A(InputStream stream) { init(stream); } // not be able to call it from outside protected final init(InputStream is){ //here goes the code } } public class B { public B(File file) { // We open the stream so we need to ensure it's properly closed try (FileInputStream stream = new FileInputStream(file)) { init(stream); } } }
I'm posting this here as a possible answer, however here i'm consdering :
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With