25

我在一些 C# 发布的问题中看到了对“使用”子句的引用。java有等价的吗?

4

12 回答 12

28

是的。Java 1.7 引入了try-with-resources结构,允许您编写:

try(InputStream is1 = new FileInputStream("/tmp/foo");
    InputStream is2 =  new FileInputStream("/tmp/bar")) {
         /* do stuff with is1 and is2 */
}

...就像一个using声明。

不幸的是,在 Java 1.7 之前,Java 程序员被迫使用 try{ ... } finally { ... }。在 Java 1.6 中:

InputStream is1 = new FileInputStream("/tmp/foo");
try{

    InputStream is2 =  new FileInputStream("/tmp/bar");
    try{
         /* do stuff with is1 and is 2 */

    } finally {
        is2.close();
    }
} finally {
    is1.close();
}
于 2008-09-26T18:56:34.397 回答
10

是的,从 Java 7 开始,您可以重写:

InputStream is1 = new FileInputStream("/tmp/foo");
try{

    InputStream is2 =  new FileInputStream("/tmp/bar");
    try{
         /* do stuff with is1 and is2 */

    } finally {
        is2.close();
    }
} finally {
    is1.close();
}

作为

try(InputStream is1 = new FileInputStream("/tmp/foo");
    InputStream is2 =  new FileInputStream("/tmp/bar")) {
         /* do stuff with is1 and is2 */
}

作为参数传递给 try 语句的对象应该实现java.lang.AutoCloseable。看看官方文档

对于较旧版本的 Java,请查看此答案此答案

于 2013-09-21T10:03:45.957 回答
5

语言中最接近的等价物是使用 try-finally。

using (InputStream in as FileInputStream("myfile")) {
    ... use in ...
}

变成

final InputStream in = FileInputStream("myfile");
try {
    ... use in ...
} finally {
    in.close();
}

请注意,一般形式始终是:

acquire;
try {
    use;
} finally {
    release;
}

如果采集在try块内,采集失败则释放。在某些情况下,您可能可以使用不必要的代码(通常在上面的示例中测试 null),但在 ReentrantLock 的情况下,会发生坏事。

如果你经常做同样的事情,你可以使用“execute around”这个成语。不幸的是,Java 的语法很冗长,所以有很多 bolier 板。

fileInput("myfile", new FileInput<Void>() {
   public Void read(InputStream in) throws IOException {
       ... use in ...
       return null;
   }
});

在哪里

public static <T> T fileInput(FileInput<T> handler) throws IOException {
    final InputStream in = FileInputStream("myfile");
    try {
        handler.read(in);
    } finally {
        in.close();
    }
}

更复杂的例子,例如,包装异常。

于 2008-09-27T14:10:42.157 回答
3

这是一个很长的时间,但在 Java 7 中添加了try-with-resources 语句以及AutoCloseable接口。

于 2012-10-05T08:50:48.023 回答
2

不是我知道的。您可以使用 try...finally 块进行一些模拟,但它仍然不完全相同。

于 2008-09-26T18:56:55.503 回答
2

在 Java 中最接近的方法是 try/finally。此外,Java 不提供隐式 Disposable 类型。

C#:在 using 块之外限定变量

public class X : System.IDisposable {

    public void Dispose() {
        System.Console.WriteLine("dispose");
    }

    private static void Demo() {
        X x = new X();
        using(x) {
            int i = 1;
            i = i/0;
        }
    }

    public static void Main(System.String[] args) {
        try {
            Demo();
        } catch (System.DivideByZeroException) {}
    }

}

Java:将变量范围限定在块之外

public class X {

    public void dispose() {
        System.out.println("dispose");
    }

    private static void demo() {
        X x = new X();
        try {
            int i = 1 / 0;
        } finally {
            x.dispose();
        }        
    }

    public static void main(String[] args) {
        try {
            demo();
        } catch(ArithmeticException e) {}
    }

}

C#:在块内确定变量的范围

public class X : System.IDisposable {

    public void Dispose() {
        System.Console.WriteLine("dispose");
    }

    private static void Demo() {
        using(X x = new X()) {
            int i = 1;
            i = i/0;
        }
    }

    public static void Main(System.String[] args) {
        try {
            Demo();
        } catch (System.DivideByZeroException) {}
    }

}

Java:在块内确定变量的范围

public class X {

    public void dispose() {
        System.out.println("dispose");
    }

    private static void demo() {
        {
            X x = new X();
            try {
                int i = 1 / 0;
            } finally {
                x.dispose();
            }
        }
    }

    public static void main(String[] args) {
        try {
            demo();
        } catch(ArithmeticException e) {}
    }

}
于 2008-09-26T19:44:49.790 回答
1

我认为你可以实现类似于“使用”块的东西,实现一个匿名内部类。就像 Spring 对“Dao 模板”所做的那样。

于 2008-09-26T19:02:46.940 回答
0

好吧,无论如何都使用语法糖,所以 Java 伙伴们,不要担心。

于 2008-09-27T11:39:29.400 回答
0

如果我们在 Java 中获得 BGGA 闭包,这也将为 Java 中的类似结构打开。Gafter 在他的幻灯片中使用了这个例子,例如:

withLock(lock) { //closure }
于 2008-10-07T13:12:15.403 回答
0

大多数程序员在第一个示例中使用的实际习惯用法是这样的:

InputStream is1 = null;
InputStream is2 = null;
try{
    is1 = new FileInputStream("/tmp/bar");
    is2 = new FileInputStream("/tmp/foo");

    /* do stuff with is1 and is 2 */

} finally {
    if (is1 != null) {
        is1.close();
    }
    if (is2 != null) {
        is2.close();
    }
}

使用这个习惯用法的缩进更少,当你有超过 2 个资源需要清理时,这变得更加重要。

此外,您可以在结构中添加一个 catch 子句,以便在需要时处理新的 FileStream() 引发的异常。在第一个示例中,如果您想这样做,则必须有另一个封闭的 try/catch 块。

于 2009-02-01T01:48:14.480 回答
-2

不,没有。

你可以

public void func(){

  {
    ArrayList l  =  new ArrayList();
  }
  System.out.println("Hello");

}

这为您提供了 using 子句的有限范围,但没有任何 IDisposable 接口来调用终结代码。您可以使用 try{}catch(){}Finally{},但它没有使用的好处。顺便说一句,在 Java 中使用终结器通常是个坏主意。

于 2008-09-26T18:59:09.117 回答
-3

不,在 Java 中没有 using,最相似的功能是“import”关键字。

于 2008-09-26T18:56:55.987 回答