Java是否具有等效于C#" using"子句的内容

时间:2020-03-06 14:47:59  来源:igfitidea点击:

我已经在一些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块。