java是否与C#“using”子句等效

时间:2008-09-26 18:52:29

标签: java syntax

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

12 个答案:

答案 0 :(得分:26)

是。 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 {...} {...}。在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();
}

答案 1 :(得分:9)

是的,因为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。看一下official docs

旧版Java结帐this answerthis answer

答案 2 :(得分: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的情况下会发生坏事。

如果你经常做同样的事情,你可以使用“执行”这个习惯用法。不幸的是,Java的语法很冗长,所以有很多更大胆的板块。

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();
    }
}

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

答案 3 :(得分:2)

不是我知道的。你可以通过try ... finally块来模拟,但它仍然不完全相同。

答案 4 :(得分:2)

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

C#:将变量置于使用块之外

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) {}
    }

}

答案 5 :(得分:2)

很长一段时间了,但是在Java 7中添加了try-with-resources statement以及AutoCloseable界面。

答案 6 :(得分:1)

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

答案 7 :(得分:0)

好吧,无论如何使用语法糖,所以Java研究员,不要冒汗。

答案 8 :(得分:0)

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

withLock(lock) { //closure }

答案 9 :(得分: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块。

答案 10 :(得分:-2)

没有。

你可以

public void func(){

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

}

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

答案 11 :(得分:-3)

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