我是.net开发人员.最近,我对比较java和c#感兴趣.我发现Java的try-with-resources相当于C#的使用块.但是,我无法完全理解它.我知道C#的using块是一种语言特性,编译器为它生成代码.我希望对资源尝试有更多的了解,并且几乎没有问题:
它是一个类似于C#使用块的语言功能吗?
以下内容的等效JDK 6代码是什么:
try(SomeResource resource = new SomeResource())
{
//Some logic
}
Run Code Online (Sandbox Code Playgroud)以下内容的等效JDK 6代码是什么:
try(SomeResource resource = new SomeResource())
{
//Some logic
}
catch(SomeException ex)
{
}
Run Code Online (Sandbox Code Playgroud)什么是Java相当于C#的Reflector或ILSpy工具?即工具来反汇编Java字节码类文件并查看它的Java代码.
假设我们使用CompletableFuture.runAsync(..)运行执行,并且在runnable中我们有try-with-resources块(我们正在使用一些应该在发生任何事情时关闭的资源),并且在某些时候在try块我们没有完成执行时取消可完成的未来...尽管执行停止,应关闭的资源未关闭,AutoClosable的close()未被调用...
这是一个java问题还是有办法正确地做到这一点?没有hacky变通办法,如使用期货(支持中断等),如果它的预期行为如何处理类似的情况,当不可中断的CompletableFuture被取消...?
public class AutoClosableResourceTest {
public static class SomeService{
public void connect(){
System.out.println("connect");
}
public Integer disconnect(){
System.out.println("disconnect");
return null;
}
}
public static class AutoClosableResource<T> implements AutoCloseable {
private final T resource;
private final Runnable closeFunction;
private AutoClosableResource(T resource, Runnable closeFunction){
this.resource = resource;
this.closeFunction = closeFunction;
}
public T get(){
return resource;
}
@Override
public void close() throws Exception {
closeFunction.run();
}
}
@Test
public void testTryWithResource() throws InterruptedException {
SomeService service = new …Run Code Online (Sandbox Code Playgroud) 我在学校学习了C#,现在我开始学习Java了.
在Java中,有"尝试使用ressources",当它不再使用时会关闭/处理东西(如扫描仪).
等效的C#是using-Statement,它基本上是一样的.
它们是真的完全相同,还是有任何差异(比如他们在后台做的事情)?
我想在每次发生事件时将(附加文本)记录到文件中.我发现这可能是使用Java 7的try-with-resources语句执行此操作的正确方法:
public void log(String textLine) {
try(PrintWriter output = new PrintWriter(new BufferedWriter(new FileWriter("Logfile.txt", true)))) {
output.println(textLine);
}catch (IOException e) {
//exception handling
}
}
Run Code Online (Sandbox Code Playgroud)
我担心的是这个日志方法被频繁调用,输出被关闭并在每次调用此方法时重新打开,这是不必要的.与此同时,我希望受益于Java 7的try-with-resources语句功能.
我的担忧不是必要的,因为重新打开和关闭作家并不是一项昂贵的操作吗?或者我应该使用Java 6的老式方法,即手动处理异常并将输出声明为成员字段并在应用程序结束时手动关闭输出?
try-with-resource构造的优先规则是什么?这是一个例子(注意:所有提到的类都实现Closeable):
try (Page closeablePage = page;
PipedOutputStream out = outs;
SequenceWriter sequenceWriter = mapper.writer().writeValuesAsArray(out)) {
// do stuff
} finally {
callback.run();
}
Run Code Online (Sandbox Code Playgroud)
回调何时运行?我的假设是:
SequenceWriterPipedOutputStreamPage我错了吗?
我一直在寻找一个CloseableHttpClient用try-with-resources 完成的例子.我很困惑,如果关闭CloseableHttpClient也会关闭CloseableHttpResponse我打电话时创建的对象httpclient.execute(post).我是否还需要CloseableHttpResponse尝试使用资源?
例:
try(CloseableHttpClient httpclient = HttpClients.custom().build()) {
HttpPost post = new HttpPost(url);
CloseableHttpResponse res = httpclient.execute(post);
// do something with res
} catch (Throwable e) {
// do something with error
}
Run Code Online (Sandbox Code Playgroud) 像这样:
public void myMethod(InputStream fileIn){
try (InputStream in = fileIn) {
do stuff....
}
}
Run Code Online (Sandbox Code Playgroud)
它似乎工作.安全吗?
当Stream在try-with-resources中使用a 时,应该关闭阅读器.
鉴于这种:
try(Stream<String> lines = new BufferedReader(reader).lines()) {
return lines.map(it -> trim ? it.trim() : it)
.collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)
......读者没有被关闭?
此测试失败:
AtomicBoolean closed = new AtomicBoolean(false);
Reader r = new StringReader(" Line1 \n Line2") {
@Override
public void close() {
super.close();
closed.set(true);
}
};
try(Stream<String> lines = new BufferedReader(r).lines()) {
lines.map(it -> trim ? it.trim() : it)
.collect(Collectors.toList());
}
assertTrue("Reader was not closed.",closed.get());
Run Code Online (Sandbox Code Playgroud) 在这个Java程序示例中:
package test;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Statement;
public class Test
{
private static void example(){
String url = "jdbc:oracle:thin:@//localhost:7856/xe";
String user = "user";
String password = "pass";
try(Connection con = DriverManager.getConnection(url, user, password);
Statement stmt = con.createStatement()){
throw new OutOfMemoryError("Error");
}catch (SQLException e){
System.err.println("SQLException");
}
}
public static void main(String [] args){
try{
example();
}catch (OutOfMemoryError e){
System.err.println("OutOfMemoryError");
}
// Rest of code here...
}
}
Run Code Online (Sandbox Code Playgroud)
当在静态方法example()的主体中抛出OutOfMemoryError错误时,在终止静态方法example()之前,Connection"con"和Statement"stmt"会自动关闭,尽管没有任何捕获这些的"catch"错误,所以在main()的其余代码中确保这两个对象是关闭的?
谢谢.
声纳给出了一个错误,FileOutputStream应该将其关闭。我需要修改以下代码才能使用try-with-resources。我该怎么做呢?
public void archivingTheFile(String zipFile){
byte[] buffer = new byte[1024];
try{
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
for(String file : this.fileList){
ZipEntry ze= new ZipEntry(file);
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream(SOURCE_FOLDER + File.separator + file);
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
in.close();
}
zos.closeEntry();
zos.close();
}catch(IOException ex){
LOGGER.error("Exception occurred while zipping file",ex);
}
}
Run Code Online (Sandbox Code Playgroud) java ×10
c# ×2
java-7 ×2
java-8 ×2
concurrency ×1
inputstream ×1
java-io ×1
java-stream ×1
sonarqube ×1
writer ×1