我有一个简单的类,它在构造函数中接受已知格式的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...
}
}