摘要
我正在研究这样一个场景:
File someFile = null;
try
{
someFile = File.createTempFile( SOME_PREFIX, SOME_SUFFIX, targetDirectory );
}
catch( IOException e )
{
throw new SomeException( "Unable to create file for domain specific task", e, SomeExceptionErrorCode.FILE_MANAGEMENT_ERROR );
}
try( BufferedOutputStream stream = new BufferedOutputStream( new FileOutputStream( someFile.getAbsolutePath() ) ) )
{
stream.write( byteData, 0, byteData.length );
stream.flush();
}
catch( IOException e )
{
throw new SomeException( "Unable to write domain specific data to domain specific file", e, SomeExceptionErrorCode.FILE_MANAGEMENT_ERROR );
}
对于这种情况,CCD_ 1是用CCD_ 2初始化的。我的意图是将此代码翻译成遵循适当实践的代码。
我的想法
- 简单地将
someFile
初始化为null
,如当前代码片段所示。然而,我通常会避免这样做,所以到目前为止,这似乎并不令人满意 - 用初始化
someFile
,例如一个空的String
。这提供了一个默认的File
实例。我看到的问题是,如果这种错误处理在未来发生变化,那么一个具有无意义属性的有效File
可能会被传递到代码中的其他位置 - 嵌套
try
-someFile
0块。这确实有效,但是由于某些原因感觉不好,特别是因为两个嵌套块都捕获了IOException
- 也考虑了
Optional<File>
,但我不相信每个try
-catch
块(其中初始化了一个稍微复杂的对象以在该块之外使用)是否都证明使用Optional
是合理的
问题
将someFile
初始化为null
是反模式吗?如果是这样的话,如何最好地处理一个场景,比如发布的场景?
这样的东西怎么样:
public void yourMethod() {
File file = createFile();
writeFile(file);
}
private File createFile() {
try {
return File.createTempFile(...);
} catch(...) {
...
}
}
private void writeFile(File file) {
try(...) {
...
} catch(...) {
...
}
}
因此,您的方法保持简洁易懂。
编辑:甚至从createFile
:返回Optional<File>
private Optional<File> createFile() {
try {
return Optional.of(File.createTempFile(...));
} catch(...) {
...
return Optional.empty();
}
}
然后您可以在null
1:中使用Optional.ifPresent
public void yourMethod() {
Optional<File> file = createFile();
file.ifPresent(value -> writeFile(value));
// or shorter:
createFile()
.ifPresent(this::writeFile);
// depends on how exactly the methods receive their parameters
}
您可以只使用
File someFile;
没有任何显式赋值。
Java通常会抱怨在变量有值之前使用该变量,但编译器足够聪明,可以理解变量可能没有值的唯一方法是createTempFile
抛出IOException
,但由于您捕捉到了throw
,它知道方法在这里退出,或者someFile
有一个正确的值。因此,允许以后使用CCD_ 26。
这比null
更干净,因为现在如果你删除了异常的重新抛出,你的代码将不再编译,因为现在编译器无法再推断总是会分配一个值。如果你用null
初始化并删除重抛出,你稍后会遇到一个NPE。
这里不需要选项,因为编译器在这种情况下可以区分未初始化的值和初始化的值。