Java Scoping & Visibility Rules

隐身守侯 提交于 2019-12-11 13:43:22

问题


I am coming back to writing code in Java after a long gap - most of my coding work over the past few years has been in PHP & JavaScript - and am discovering that I have to work harder to satisfy the Java compiler which is far more rigorous about issues such as variable scope and exception handling. A piece of code that caused me some trouble is shown below

File file = new File(path, fname);
FileOutputStream stream = null;
try 
{
 stream = new FileOutputStream(file);
 stream.write(tosave.getBytes());
}
finally 
{
 try
 {
  if (null != stream) {stream.close();}
  return true;
 }
 catch(Exception e){return false;}        
}

This is accepted by the compiler. However, before I got here I had run into several issues.

  • First attempt: No Catch Block. The compiler refused to play ball because it wanted me to deal with the eventuality that the FileOutputStream could not be created. Ditto for writing to that stream. I understand the logic behind this reasoning and like it.
  • Second attempt: Catch Block but...:I was declaring and creating the stream variable INSIDE the try block. The compiler threw a wobbly again - the stream variable was out-of-scope in the finally block.

As you will see I have gotten around the issue by declaring stream above the try block and initializing it to null.

This works. However, given just how rusty my Java skills are I thought I would ask: Is there a right way to write such code?


回答1:


The idiomatic way to handle such scenarios in modern Java versions (since Java 7) would be to use a try-with-resource block that handles all the ugly closing "logic" for you. You'd still have to either catch the exception or propagate it upwards, but that's a relatively small issue. Consider the following:

public static boolean writeToFile(String path, String fname) {
    File file = new File(path, fname);
    try (FileOutputStream stream = new FileOutputStream(file)) {
        stream.write(tosave.getBytes());
    } catch (IOException e) {
        // Should probably log the exception too
        return false;
    }
    return true;
}



回答2:


You could simply use below code snippet:

try (FileOutputStream stream = new FileOutputStream(file)){
    stream.write(tosave.getBytes());
}catch(IOException e) {
    e.printStackTrace();
    return false;
}

return true;

It's a new feature (try-with-resources Statement) introduced in Java 7.




回答3:


I think you're getting hung up on stuff that isn't important. Yes, in some situations coding try/catch/finally IS important because you actually need to do something to fix an error.

But for opening/closing a file, you don't want to get yourself into knots just to satisfy the compiler. Code Readability is much more important.

How about:

String path="somepath";
String fname="somefile";
String tosave="somedata";
try {
    File file = new File(path, fname);
    FileOutputStream stream = new FileOutputStream(file);
    stream.write(tosave.getBytes());
    stream.close();
}
catch (Exception e) {
    e.printStackTrace();
    return false;
}
return true;



回答4:


The "right" way is to use Java 7's try with resources. It has been a long time coming, but it cleans up this sort of boilerplate code really well.

Tough luck if you are stuck on an earlier Java version :)



来源:https://stackoverflow.com/questions/36934061/java-scoping-visibility-rules

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!