当你想链接构造函数时,如何处理IO句柄?



我有一个简单的类,它在构造函数中接受已知格式的InputStream。在给对象的私有成员赋值之前,所有繁重的工作都在这个构造函数中完成:

public class TestClass {
private Integer something;

public TestClass(InputStream istream) {
// Long and complex something-something
// ...

// Assign value after lots of processing
something = 123;
}
}

现在我决定我还想提供一个接受File的构造函数。我可以很容易地像这样链接构造函数:

public TestClass(File file) {
this(new FileInputStream(file));
}

呃哦!我忘了关小溪了!

public TestClass(File file) {
InputStream istream = new FileInputStream(file);

try {
// Error: Constructor call must be the first statement in a constructor
this(istream);
}
finally {
istream.close();
}
}
以这种方式链接构造函数是不允许的。Java规定从另一个构造函数调用一个构造函数必须是第一个语句。

我试图把所有东西都塞进一个处理初始化的方法中,但Java编译器仍然对我的构造函数有未初始化的变量大吼大叫:

public class TestClass {
private Integer something;

// Error: The field something may not have been initialized
public TestClass (InputStream istream) {
doInit();
}

// Error: The field something may not have been initialized
public TestClass (File file) {
InputStream istream = new FileInputStream(file);

try {
doInit(istream);
}
finally {
istream.close();
}

}

private void doInit(InputStream istream) {
something = 123;
}
}

除了简单地删除构造函数,接受一个File,只接受一个流,有没有一种方法,使这个工作呈现?

我的实际代码有多个成员变量被初始化,所以它不像传递流给静态方法并返回值那么简单,因为这最多只能初始化一个变量。

一个解决方案是使用静态方法:

public class TestClass {
public static TestClass fromFile(File file) throws IOException {
try (FileInputStream input = new FileInputStream(file)) {
return new TestClass(input);
}
}
public TestClass(InputStream input) throws IOException {
// initialize instance...
}
}

最新更新