在Java 17中,我有一个生成树结构的序列化器。在生成子实体之前,我增加了缩进级别;然后我降低缩进级别。通常情况下,应该在try
/finally
中完成,以防止串行器在出现错误时处于损坏状态:
increaseIndentLevel();
try {
serializeChildren()
} finally {
decreaseIndentLevel()
}
使用try-with-resources,我创建了一个聪明而优雅的小子框架,以更流畅的方式确保这一点:
protected Closeable increaseIndentLevel() {
indentLevel++;
return Close.by(this::decreaseIndentLevel);
}
Close.by()
是我的助手类,它创建了一个Closeable
,可以像上面一样降低缩进级别;我可以这样使用它:
try (final Closeable indention = increaseIndentLevel()) {
serializeChildren()
}
不幸的是,OpenJDK javac 17打开了linting,并没有意识到我的聪明,而是抱怨道:
[警告] auto-closeable resource indention is never referenced in body of corresponding try statement
我知道try-with-resources需要声明一些变量。例如,我不能说try (increaseIndentLevel())
。(我也能猜到原因:这个特性的创建者没有足够的概括,而是为明显的99%的用例创建了不必要的限制性规则。实际上,在概念上不需要在这里要求变量;如果主体需要引用某些内容,编译器足够聪明,可以注意到引用的变量不存在。
你知道怎么避开这个警告吗?
作为最后的手段,我应该在@SuppressWarnings()
中使用什么标识符来消除javac中的这个警告?(我不得不压制警告,因为它把这样一个漂亮的解决方案变成了如此丑陋的东西。)
3条答案
按热度按时间x3naxklr1#
我会写这样的东西来避免易变性。如果没有看到更多的用例,很难知道该建议什么:
x7yiwoj42#
从@Mihe对这个问题的评论中得到提示,一个解决方案是编译器本身的disable the
try
linting,就像Maven中的这样:我还是觉得这有点过分我考虑重构代码以使用@tgdavies的函数式方法,但我还没有做出决定。我想我提供这个解决方案是为了完整性。
goqiplq23#
我最终做的是在我的Close实用程序中添加一个额外的(noop)帮助器方法。
另一种方法是添加到关闭收集器:
我更喜欢第一个。两者都添加了两行,其中一行是空的。第一种在实现和可读性上都要简单得多,而且它得到了优化。