2 Replies Latest reply: May 12, 2014 5:42 PM by rp0428 RSS

    final field initialization with exceptions

    swpalmer

      consider:

       

      class A {

           final Object b;

           public A(C c) {

                try {

                     b = c.someMethodThatMayThrowSomeException();

                } catch (SomeException e) {

                     b = null; // This line results in compiler error: "variable b might already have been assigned"

                }

           } // take away b=null line and you get "variable b might not have been initialized" on this line

      }

       

      Why?

      How could 'b' be assigned if the exception was thrown?

       

      Is this a bug, or am I missing something?

       

      Btw, the workaround is to wrap the method call:

       

      private final Object initB() {

           try {

                return c.someMethodThatMayThrowSomeException();

           } catch (SomeException e) {

                return null;

           }

      }

       

      and use b = initB(); in the constructor.  But that seems like it should be unnecessary.

        • 1. Re: final field initialization with exceptions
          TPD-Opitz

          the whole point in the final keyword on member variables is that we can trust in that variable never being null.

           

          There are two ways to handle this situation:

          1. don't pass c to the constructor but the value returned by the method call.
          2. a) don't handle the exception thrown by the method call.
            b) wrap the caught exception in a RuntimeException and throw that.

           

          The "work around" you found is dangerous because other programmers will not expect this member being null so NPEs will occure often...

           

          bye

          TPD

          • 2. Re: final field initialization with exceptions
            rp0428

            If you want us to comment on code constructs you need to post the actual code.

             

            The code you posted is incomplete so it can't possiblly give the error you say it does.

             

            Post the actual code that supports your statements.