Java是否具有等效于C#" using"子句的内容
我已经在一些Cposted问题中看到了对" using"子句的引用。
java是否具有等效功能?
解决方案
是的。 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(); }
不是我知道的。我们可以使用try ... finally块进行某种程度的模拟,但是仍然不尽相同。
不,在Java中没有使用,最相似的功能是" import"关键字。
不,没有。
你可以
public void func(){ { ArrayList l = new ArrayList(); } System.out.println("Hello"); }
这为using子句提供了有限的范围,但是没有任何IDisposable接口可以调用终结代码。我们可以使用try {} catch(){} Finally {},但它没有使用的便利。顺便说一句,在Java中使用终结器通常不是一个好主意。
我认为我们可以实现类似于" using"块的方法,并实现一个匿名内部类。像Spring那样使用" Dao模板"。
我们可以在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) {} } }
好吧,反正使用语法糖还是Java伙伴,请不要费力。
语言中最接近的等效项是使用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(); } }
例如,更复杂的示例可以包装异常。
如果我们在Java中获得了BGGA闭包,那么这也将为Java中的类似结构敞开大门。 Gafter在幻灯片中使用了此示例,例如:
withLock(lock) { //closure }
大多数程序员在第一个示例中使用的实际习惯用法是:
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块。