try-with-resource 不声明变量

try-with-resource without declaring variable

我想使用 try-with-resource 来切换上下文,但似乎 try() 不能在不声明变量的情况下使用资源,这会降低代码的优雅度。例如

class SwitchContext implements Closeable {
   public SwitchContext(String newContext) {
     //Set new context to local thread
   }

   public void close() {
     //Restore old context to local thread
   }

和用法:

String func() {
  try (new SwitchContext(newContext)) {
     //Do something
     return "dummy";
  }

void func2() {
  try (new SwitchContext(newContext)) {
     //Do something
  }

但是我在 try() 上遇到语法错误。只有当我这样写时: try (SwitchContext c = new SwitchContext(newContext)) { 它通过编译。 最优雅的方法是什么?

更新

由于在某些答案中人们不明白我要做什么,所以我会尝试更好地解释。我正在尝试以更优雅的方式执行以下逻辑:

void func() {
   Context old = ContextUtil.getCurrentContext();
   try() {
       ContextUtil.setContext(A)
       //Do something or call other methods
       //Any method than need the context use ContextUtil.getCurrentContext()
   } finally () {
      ContextUtil.setContext(old)
   }
}

不丢弃新对象的引用

new命令returns对新实例化对象的引用。您的代码尝试会丢弃该引用。因此,您要遵循的 none 代码可以访问该实例化的资源对象。创建一个不能使用的资源对象是没有意义的。

解决方案是创建一个引用变量,我们可以在其中捕获新创建的资源对象的引用。

String func() {
    try (
        SwitchContext context = new SwitchContext( newContext ) ;
    ) {
    // Do something with that resource.
    String result = context.calculate() ;
    return result ;
}
// At this point, `SwitchContext#close` has been called and executed, closing our resource object. 

您评论说,«这不是真正的新资源»。如果您的意思是您要利用并自动关闭的对象已经实例化,请使用不同形式的 try-with-resources。

在更高版本的 Java 中,您的 try-with-resources 可以访问并自动关闭之前实例化的资源。

SwitchContext context = new SwitchContext( newContext ) ;
… more code …
String func() {
    try (
       context
    ) {
    // Do something with that resource.
    String result = context.calculate() ;
    return result ;
}
// At this point, `SwitchContext#close` has been called and executed, closing our resource object. 

Try-with-resources 就是调用 close

请记住,使用 try-with-resources 的全部意义在于让 JVM 自动调用资源的 close 方法。如果调用 close 不是您的本意,请在您的代码中使用不同的控制流结构。

The try-with-resources statement is a try statement that declares one or more resources

来自 Oracle tutorial.

长话短说:语言的句法就是它的本来面目。当语言要求 声明 时,这就是您必须在代码中添加的内容。

或者,如果您想要正式的东西,请查看 JLS:

TryWithResourcesStatement:
try ResourceSpecification Block [Catches] [Finally]

ResourceSpecification:
( ResourceList [;] )

ResourceList:
Resource {; Resource}

Resource:
LocalVariableDeclaration
VariableAccess
VariableAccess:
ExpressionName
FieldAccess