with try examples convert close catch java java-8 try-with-resources

java - try - Probar con recursos al llamar a super constructor



try with resources jdbc (3)

¿Hay alguna buena manera de usar try-with-resources al abrir un InputStream en un constructor y luego pasárselo a un super constructor?

Básicamente lo que quiero hacer es esto:

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)); } } }

Pero, por supuesto, ya que super debe ser la primera declaración en el constructor, esto no está permitido. ¿Hay alguna buena manera de lograr esto?


Considere usar un método de fábrica estático en lugar de usar el constructor directamente. Haga que al menos el constructor de B privado, y cree un método como

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; }


Lamentablemente no tengo un compilador a mano para probar, pero no podrías hacer lo siguiente.

public class B { private static InputStream file2stream(File f){ // We open the stream so we need to ensure it''s properly closed try (FileInputStream stream = new FileInputStream(file)) { return stream; }catch(/*what you need to catch*/){ //cleanup // possibly throw runtime exception } } public B(File file) { super(file2stream(file)) } }


Otra forma de ir:

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); } } }

Estoy publicando esto aquí como una posible respuesta, sin embargo aquí considero:

  1. Puede actualizar el código de A
  2. Está moviendo el código del constructor a un método de inicio, gracias al constructor de argumento vacío protegido, solo las subclases tienen que manejar la llamada para iniciar correctamente. Algunos pueden ver que no está tan bien diseñado. Mi punto es que tan pronto como subcompones algo, debes saber más sobre eso que cuando lo usas.