java - 当您想要链接构造函数时,如何处理 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;
}
}
除了简单地删除接受 aFile
并且只接受流的构造函数之外,有没有办法让这个工作像呈现的那样?
我的实际代码有多个正在初始化的成员变量,因此它不像将流传递给静态方法并返回一个值那么简单,因为这最多只能初始化一个变量。
解决方案
一种解决方案是使用静态方法:
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...
}
}
推荐阅读
- c - 使用 scanf() 的管道的意外行为
- gradle - gradle build 异常失败
- node.js - 在 `npm install` 之前用 dotenv 替换 .npmrc 中的 env 变量
- here-olp - 使用包 API 创建 jar 包时收到 HTTP 400 (E9999)
- javascript - 如何正确地将 onclick 事件添加到 JS 中创建的 DOM 按钮元素?
- amazon-web-services - 检查 Redshift 是否正在进行维护?
- r - Phyloclim R 包的函数“niche.overlap”中的问题
- ruby-on-rails - perform_later 和 perform_async 有什么区别?
- c# - 为什么当应用程序在我的计算机上运行时 System.DateTime.Now 工作,但当我通过工作组启动应用程序时不工作?
- spring-boot - spring-boot-starter-quartz 指定不同的数据库连接器?