我的疑问主要出现在读取套接字时,在以下代码中:
String hostName = args[0];
int portNumber = Integer.parseInt(args[1]);
try (
Socket echoSocket = new Socket(hostName, portNumber);
PrintWriter out =
new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in =
new BufferedReader(
new InputStreamReader(echoSocket.getInputStream()));
BufferedReader stdIn =
new BufferedReader(
new InputStreamReader(System.in))
) {
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
}
链接:http://docs.oracle.com/javase/tutorial/networking/sockets/examples/EchoClient.java
在上面的代码中,据我所知,PrintWriter和BufferedReader是资源,但我也在trywithreasources块中读取,一旦它结束,其中的所有资源都被关闭。但是如果关闭资源意味着破坏对象,那就意味着stdIn和in被销毁,并且它是块之外的单独实例。是这样吗?
答案 0 :(得分:0)
查看您的try-with-resources
,我们只选择包裹System.in
的部分。
try (
...
BufferedReader stdIn =
new BufferedReader(
new InputStreamReader(System.in))
)
stdIn
是一个包装InputStreamReader
对象的对象,它包装了InputStream
个对象。那个InputStream
对象是(除非你已经改变它)Java进程的标准输入。
当您退出try
屏蔽时,它会调用stdIn.close()
,它会级联并致电close()
InputStreamReader
,close()
会级联并呼叫System.in
在{{1}}引用的对象上。
Java中没有破坏。如果上述变量引用的对象在程序中无法访问,则它们将被垃圾回收。
答案 1 :(得分:0)
try-with-resource语句只会关闭try内部括号中声明的资源。
try ( /*anything declared here will be closed*/) {
}
当try尝试结束时,try with resource将在声明的任何资源上调用close()
。这不一定像C中的析构函数一样“破坏”对象,但它通常以这种方式使用。该变量也将超出try之外的范围,因此可以进行垃圾回收。
在您的示例中stdIn
换行System.in
,以便System.in
将被关闭。但是,由于它在尝试后仍然在范围内,因此不会进行垃圾回收。 (但你不能再写了)
Try-with-resource只是“合成糖”,将被编译成这样的东西:
Socket echoSocket =null
PrintWriter out =null
BufferedReader in =null
BufferedReader stdIn =null
try{
echoSocket = new Socket(hostName, portNumber);
out =
new PrintWriter(echoSocket.getOutputStream(), true);
in =
new BufferedReader(
new InputStreamReader(echoSocket.getInputStream()));
stdIn =
new BufferedReader(
new InputStreamReader(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
}
}finally{
if(stdIn !=null){
try{
stdIn.close()
}catch(Exception e){
//surpress exception if needed
}
}
if(in !=null){
try{
in.close()
}catch(Exception e){
//surpress exception
}
}
if(out !=null){
try{
out.close()
}catch(Exception e){
//surpress exception
}
}
if(echoSocket !=null){
try{
echoSocket.close()
}catch(Exception e){
//surpress exception
}
}
}
请注意,资源以相反的顺序关闭以解决嵌套问题。如果某个东西在try块中引发异常并且其他东西在finally块中引发了异常,那么“surpress exception”会被添加到原始的Exception对象中,该对象可以通过新的Throwable.getSuppressed()
方法进行检索。这样堆栈跟踪正确显示了try中抛出的原始异常。
有关try-with-resource的更多信息,请参阅Oracle教程:http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
答案 2 :(得分:0)
如果关闭资源意味着破坏对象
没有。 Java中没有“破坏”这样的东西。
这意味着stdIn和in被销毁
不,不。
并且它是块外的单独实例。是这样吗?
没有