简体   繁体   English

在调用超级构造函数时尝试使用资源

[英]Try-with-resources when calling super constructor

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? 在构造函数中打开InputStream然后将其传递给超级构造函数时,有没有什么好的方法可以使用try-with-resources?

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. 但是,当然,因为super必须是构造函数中的第一个语句,所以这是不允许的。 Is there any good way of achieving this? 有没有什么好办法实现这个目标?

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 至少将B的构造函数设为私有,并创建一个方法,如

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 : 我在这里发布这个作为一个可能的答案,但是在这里我正在考虑:

  1. You can update A's code 您可以更新A的代码
  2. You're moving constructor's code to an init method, thanks to protected empty arg constructor, only subclasses have to handle the call to init properly. 您正在将构造函数的代码移动到init方法,这要归功于受保护的空arg构造函数,只有子类必须正确处理对init的调用。 Some may see that as not so well designed. 有些人可能会认为设计不太好。 My point is as soon your subclassing something, you have to know more about it that just when you just using it. 我的观点是,一旦你继承了一些东西,你只需要在使用它时就必须了解它。

Sadly I do not have a compiler on hand to test on but could you not do as follows. 遗憾的是,我手边没有编译器可以进行测试,但是你可以不按照以下方式进行测试。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM