Hacker News new | ask | show | jobs
by mquander 5518 days ago
That seems like a pretty serious argument to me. Not only is it a pain in the ass to remember and write that every time you consume a resource that needs to be released somehow, it also introduces all kinds of scoping headaches in Java. If mightFail() returns a value that you want to use after cleanup (i.e. all the time,) then you have to declare the variable to store that value outside of the try {} block.
1 comments

> [...] then you have to declare the variable to store that value outside of the try {} block

That's kind of the point. The variable will only be assigned a value if mightFail returns normally. The scoping rules make it impossible to accidentally use an uninitialized variable (i.e. a variable whose first assignment was not reached due to an exception).

I take it that you're imagining a case like this:

  try {
    var result = mightFail();
  }
  catch {
    handleError();
  }
  finally {
    cleanup();
  }

  print(result) // we don't want to allow this
That's true, the scoping protects you from making that mistake. However, the more common case is this:

  try {
    var result = mightFail();
  }
  finally { // let the exception bubble up
    cleanup();
  }

  print(result); // this must be OK, but I can't do it in Java
There are two things I can do to fix the latter case. I can either declare the variable outside the block, adding a silly-looking extra line of code, or I can move the print() within the block, which can be problematic -- it means that if print() were something time-consuming, I would be holding onto the resource during print() for no reason. I think this is a crappy thing to force onto the programmer.
Sure. Another alternative is to pull the try/catch/finally into a separate function that just returns the value. But that's not always convenient, YMMV, etc. Either way, I'd consider it just an occasional annoyance (occasional because frequently print() is quick, or the resource is not expensive or contended).