• Post Reply Bookmark Topic Watch Topic
  • New Topic

variable "may not have been initialized" in try/catch block style question  RSS feed

 
Chad Schultz
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm initializing different variables in try/catch blocks, and then when I use the variables the compiler tells me that they may not have been initialized. IT thinks that if an exception is caught, the variable won't be initialized- it doesn't realize that my catch blocks call a method which spits out an error and calls System.exit(1);

How do I make the "variable may not have been initialized" error go away?

This question has been sort of answered elsewhere; declare your variables outside the try/catch block, initialize them to default or null values outside the try/catch block so the compiler will shut up, and so on.

However, what about objects that MUST be initialized in a try/catch block, such as FileWriters?


I also could pile the execution code in the try block, which is very poor design, as that code won't produce the exception.

Or I could call a method from inside the try block and pass the variable there- oh, but what about the other objects/variables? This only works for one...
...unless I cram all the different objects into a single try block, and catch a slew of different exceptions. I could be mistaken, but that doesn't seem like good style either.

Or I could throw a RuntimeException in the catch block... right after the call to my special exiting method, so it would never be reached anyway.

Is there any good way to handle this kind of situation?
 
Peter Chase
Ranch Hand
Posts: 1970
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Don't System.exit(). It's a very ugly way to "handle" an exception.
 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Put the initialisation outside the try block. Like this
 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
. . . and for FileWriters, try thisI am not quite sure whether you still use BufferedWriters like that-please check.

This format ensures:
  • Your variables are all initialised before use.
  • You can be absolutely confident that your file writers are closed after use.
  • If you write "new BufferedWriter(new FileWriter(fileName))", you only need to declare and close the BufferedWriter object.
     
    Ricky Clarkson
    Ranch Hand
    Posts: 131
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    You could always just put a return statement after the System.exit(1);

    Try posting some relevant code.
     
    Campbell Ritchie
    Marshal
    Posts: 56525
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    A return after System.exit(1)? Won't that cause a compiler error as "unreachable code"?
     
    Ricky Clarkson
    Ranch Hand
    Posts: 131
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    No, it doesn't. I just tried it, and you can infer it from the original question anyway.
     
    Tony Morris
    Ranch Hand
    Posts: 1608
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Campbell Ritchie:
    . . . and for FileWriters, try this


    Every time you assign a local to null think, "there is always a better way". Answering the original poster is a little difficult without more detail on the intention, but if it for opening and closing resources, the above code can be improved by embedding try/finally blocks in try/catch blocks. There is never a need to assign to null and the above code is quite dangerous and could lead to a resource leak. Here is pseudo-code for the original poster:


    If you have multiple resources:



    Note: You may be puking at the verbosity of the corrected code at this point, but please do not shoot the messenger. I didn't write this language. Heck, I do not even encourage its use for anything practical.
    [ May 18, 2007: Message edited by: Tony Morris ]
     
    Ricky Clarkson
    Ranch Hand
    Posts: 131
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Tony, that's not great, because you shouldn't let an exception escape a finally block, to stomp all over the exception that's already been thrown. Catch it and log it.



    Practically, there's no reason not to use the 'null' version. Null isn't so much of a problem if it can't escape the current scope:



    Of course, you can wrap this up to make nesting it less ridiculously complex. The only bits that really vary are the way to open a resource and the way to use it.



    Which would be used like so:



    Of course, there's only actually three lines of code in all that that are actually useful, and it seems a shame to have to have a separate SideEffectWithException as well as SideEffect.

    You might think the above is poor code. It isn't, it's just code that's fighting against the language somewhat. Here's the same code in what Java 7 will likely look like:

    Now it doesn't look so bad, does it?

    [ inserted line breaks in overlong line of code - Jim ]
    [ May 20, 2007: Message edited by: Jim Yingst ]
     
    Tony Morris
    Ranch Hand
    Posts: 1608
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I agree regarding the "swallowed exception", but not to the fact that there is nothing wrong with using the null assignment version (I'd opt for your "messy" version and concede that I'm using a "messy" language).

    Regarding your Java 7 version, it is called the Loan Pattern in Java version 42 http://scala.sygneca.com/patterns/loan

    Why *are* you still using such an obsolete (messy?) language anyway? How is Haskell hacking going?
     
    Ricky Clarkson
    Ranch Hand
    Posts: 131
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I decided that, at least for now, Haskell isn't for me. I don't need shackles to write programs, even if I can invent my own shackles.
     
    Chad Schultz
    Greenhorn
    Posts: 23
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Wow. I didn't expect quite that many responses! I'm especially surprised to see people slamming Java in a Java forum.

    Thanks everyone for your ideas. It looks like people mainly suggested calling the method to run the actual code from inside the try block. I thought that didn't look right when I had four successive try/catch blocks (one for each command line argument) with the method call hidden away in the last one, but that's just me.

    I ended up putting all the initializing try/catch blocks into a separate method. They each set a class variable. In case something does go wrong, the catch blocks call a method that logs the error and exits the program. Then I have the main method call that method (no gripes about uninitialized variables!), and then the other methods of the class that perform the actual functionality. I feel that leads to clean code, the separate methods are easier to test, and then my main method gives a "bird's eye view" of the flow.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!