调用超级构造函数时尝试使用资源
Try-with-resources when calling super constructor
在构造函数中打开 InputStream
然后将其传递给超级构造函数时,是否有使用 try-with-resources 的好方法?
基本上我想做的是:
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));
}
}
}
但是,当然,因为 super
必须是构造函数中的第一条语句,所以这是不允许的。有什么好的方法可以实现吗?
考虑使用静态工厂方法而不是直接使用构造函数。至少将 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;
}
另一种方法:
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);
}
}
}
我在这里发布这个作为可能的答案,但是我在这里考虑:
- 你可以更新A的代码
- 您正在将构造函数的代码移动到 init 方法,这要归功于受保护的空 arg 构造函数,只有子类必须正确处理对 init 的调用。有些人可能会认为它的设计不太好。我的观点是,一旦你对某些东西进行子类化,你就必须在使用它的时候更多地了解它。
遗憾的是我手头没有编译器可以测试,但你能不能不这样做。
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))
}
}
在构造函数中打开 InputStream
然后将其传递给超级构造函数时,是否有使用 try-with-resources 的好方法?
基本上我想做的是:
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));
}
}
}
但是,当然,因为 super
必须是构造函数中的第一条语句,所以这是不允许的。有什么好的方法可以实现吗?
考虑使用静态工厂方法而不是直接使用构造函数。至少将 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;
}
另一种方法:
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);
}
}
}
我在这里发布这个作为可能的答案,但是我在这里考虑:
- 你可以更新A的代码
- 您正在将构造函数的代码移动到 init 方法,这要归功于受保护的空 arg 构造函数,只有子类必须正确处理对 init 的调用。有些人可能会认为它的设计不太好。我的观点是,一旦你对某些东西进行子类化,你就必须在使用它的时候更多地了解它。
遗憾的是我手头没有编译器可以测试,但你能不能不这样做。
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))
}
}