Toward more extensive use of final

Discussion in 'Java' started by Roedy Green, Mar 7, 2006.

  1. Roedy Green

    Roedy Green Guest

    I have been working with IntelliJ which keeps making suggestions to
    improve you code. One thing it likes to do is add finals wherever it
    can.

    This presumably helps the compiler generate better code at it makes
    clear to maintenance programmers what you can count on staying fixed.

    There are two idioms you might not know that allow final:


    private static final int x;

    static {

    x = complicated Expression involving other constants;
    }

    This is good when order of initialisation matters. If you put the
    code inside a static init, the order can't be ruined by a
    code-beautifier that alphabetises or otherwise reorders fields.

    also

    private final int x;

    Constructor ( )
    {
    x = something;
    }
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
    Roedy Green, Mar 7, 2006
    #1
    1. Advertising

  2. Be careful, though, in both cases the field may be exposed to external
    viewers before being assigned, and this will have the most undesirable
    effect of having the "final" value change.
    Stefan Schulz, Mar 7, 2006
    #2
    1. Advertising

  3. Roedy Green

    Jacob Guest

    Roedy Green wrote:

    > private final int x;
    >
    > Constructor ( )
    > {
    > x = something;
    > }


    Sometimes this is not possible, for instance if "something" is
    declared to throw an exception. The common pattern is then to
    first assign to a temporary variable before assiging to the
    class variable, as the final can be assigned just once inside
    the ctor:

    Constructor()
    {
    int tmp;
    try {
    tmp = something;
    }
    catch (Exception e) {
    tmp = somethingElse;
    }

    x = tmp;
    }
    Jacob, Mar 7, 2006
    #3
  4. Roedy Green wrote:
    >
    > This presumably helps the compiler generate better code at it makes
    > clear to maintenance programmers what you can count on staying fixed.


    Slightly better code from the java source->byte code compiler for static
    fields (constant expressions). From 1.5 byte code->machine code compiler
    can make assumptions that final fields do not have to be reread after
    synchronisation and volatile operations. Final local variables make no
    difference from a performance perspective.

    > private static final int x;
    >
    > static {
    >
    > x = complicated Expression involving other constants;
    > }


    Rather irritatingly you can't qualify the assignment for statics:

    class MyClass {
    private static final OtherClass thing;
    static {
    OtherClass thing = new OtherThing();
    ... configure thing ...
    MyClass.thing = thing; // compile error
    }
    ...
    }

    IIRC, in Effective Java, Josh Bloch recommends using static creation
    methods instead:

    class MyClass {
    private static final OtherClass thing = descriptiveMethodName();
    ...
    private static OtherClass descriptiveMethodName() {
    OtherClass thing = new OtherThing();
    ... configure thing ...
    return thing;
    }
    }

    > This is good when order of initialisation matters. If you put the
    > code inside a static init, the order can't be ruined by a
    > code-beautifier that alphabetises or otherwise reorders fields.


    If you put all static initialisation in static initialisers. Code
    reordering is still likely to make a mess if you go for static
    initialisers next to declarations.

    > private final int x;
    >
    > Constructor ( )
    > {
    > x = something;
    > }


    I much prefer to always qualify instance field in constructors (and
    setters) with this..

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
    Thomas Hawtin, Mar 7, 2006
    #4
  5. Roedy Green

    Guest

    Roedy Green wrote:
    > private static final int x;
    >
    > static {
    >
    > x = complicated Expression involving other constants;
    > }
    >


    Careful with that - if "complicated expression" throws an exception,
    you'll get an ExceptionInInitializerError, and the class won't be
    loaded - and if your app survived that, next time
    you try to use that class withing the app you'll get a
    NoClassDefFoundException.

    (somebody please correct me if I'm wrong)
    , Mar 7, 2006
    #5
  6. wrote:
    > Roedy Green wrote:
    >> private static final int x;
    >>
    >> static {
    >>
    >> x = complicated Expression involving other constants;
    >> }
    >>

    >
    > Careful with that - if "complicated expression" throws an exception,
    > you'll get an ExceptionInInitializerError, and the class won't be
    > loaded - and if your app survived that, next time
    > you try to use that class withing the app you'll get a
    > NoClassDefFoundException.


    I think it wont compile if the static block can throw an exception.

    /tom
    tom fredriksen, Mar 7, 2006
    #6
  7. Roedy Green wrote:
    > I have been working with IntelliJ which keeps making suggestions to
    > improve you code. One thing it likes to do is add finals wherever it
    > can.
    >
    > This presumably helps the compiler generate better code at it makes
    > clear to maintenance programmers what you can count on staying fixed.
    >
    > There are two idioms you might not know that allow final:
    >
    >
    > private static final int x;
    >
    > static {
    >
    > x = complicated Expression involving other constants;
    > }
    >
    > This is good when order of initialisation matters. If you put the
    > code inside a static init, the order can't be ruined by a
    > code-beautifier that alphabetises or otherwise reorders fields.
    >
    > also
    >
    > private final int x;
    >
    > Constructor ( )
    > {
    > x = something;
    > }


    I am not sure I understand what you are getting in this post.
    You are listing three points 1) intellij and finals, 2) musings on
    finals in compilation and 3) idioms for using final.
    AFAICT, you are not making a suggestion or conclusion, could you please
    elaborate.

    /tom
    tom fredriksen, Mar 7, 2006
    #7
  8. Hi,

    tom fredriksen wrote:
    >> Roedy Green wrote:
    >>
    >>> private static final int x;
    >>>
    >>> static {
    >>>
    >>> x = complicated Expression involving other constants;
    >>> }
    >>>

    >>
    >> Careful with that - if "complicated expression" throws an exception,
    >> you'll get an ExceptionInInitializerError, and the class won't be
    >> loaded - and if your app survived that, next time
    >> you try to use that class withing the app you'll get a
    >> NoClassDefFoundException.

    >
    > I think it wont compile if the static block can throw an exception.


    It will compile and the static block can throw a RuntimeException.

    Ciao,
    Ingo
    Ingo R. Homann, Mar 7, 2006
    #8
  9. Roedy Green

    Roedy Green Guest

    On Tue, 07 Mar 2006 16:52:53 +0100, tom fredriksen <>
    wrote, quoted or indirectly quoted someone who said :

    >I am not sure I understand what you are getting in this post.
    >You are listing three points 1) intellij and finals, 2) musings on
    >finals in compilation and 3) idioms for using final.
    >AFAICT, you are not making a suggestion or conclusion, could you please
    >elaborate.


    There is nothing to explain. You understand perfectly.
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
    Roedy Green, Mar 7, 2006
    #9
  10. Roedy Green

    Guest

    Hi Roedy,

    first thanks a lot for mindprob.com!

    > I have been working with IntelliJ which keeps making
    > suggestions to improve you code. One thing it likes to
    > do is add finals wherever it can.


    If you let him do it (which I certainly do). But you can customize
    everything (like asking him to propose or not final for method
    parameters, etc.): convenient for people who have their preferred
    way of doing it (and who thinks that it's better than Jetbrain's
    default config, but that is another topic ;)


    > This presumably helps the compiler generate better code at
    > it makes clear to maintenance programmers what you can
    > count on staying fixed.


    And it surely helps IntelliJ's own (incredible IMHO) real-time
    source code parser to make very relevant comments like
    "condition xxx will always be true" or "code here will never
    be executed" etc.

    I'm not talking about the usual compiler messages, but
    messages made possible by IDEA's own Java source
    tree framework (available to anyone willing to write
    plugins for IDEA btw).

    I've had case where I'd just stop, think a little bit and
    realize "oh my, IntelliJ is right!" just followed by
    "how could he know that!?". Then I realize that it's
    been analyzing the code quite extensively and used
    all the infos it had (like that tiny little "final" modifier
    here and there) to eventually make its correct statement.

    What I'm saying is that I *know* what IDEA's parser
    is capable of, but once it while it still surprises me.

    IDEA's parser is good, very good. And any hint you give
    hime just makes him better.

    Bye and thanks again for mindprob,

    Driss
    , Mar 7, 2006
    #10
  11. Roedy Green

    Guest

    Stefan Schulz wrote:
    > Be careful, though, in both cases the field may be exposed to external
    > viewers before being assigned, and this will have the most undesirable
    > effect of having the "final" value change.


    Hi,

    can you show me an example of how the following field could
    be exposed to an external viewer before the object being
    constructed ?

    How could any external viewer access a private instance field
    before having a reference to the object ?


    Roedy's (second) example
    > private final int x;
    >
    > Constructor ( ) {
    > x = something;
    >}
    , Mar 7, 2006
    #11
  12. Roedy Green

    Guest

    > public class A {
    > private final int x;
    > A() {
    > new B(this);
    > this.x = 42;
    > }
    > public int getX() {
    > return x;
    > }
    > }
    >
    > public class B {
    > public B(A a) {
    > System.err.println(a.getX();
    > }
    > }


    thanks!
    , Mar 7, 2006
    #12
  13. Roedy Green

    Guest

    Hello again,

    I added to "System.out" to your example and
    ran it from IntelliJ IDEA...

    41 appears in the color black at the console.
    0 appears in red
    43 appears in black.

    Can somebody explain me what is going on?
    (I realize that 0 appears because it hasn't
    been initialized, but how does the console
    notice that?)

    class B {
    public B(A a) {
    System.out.println("41");
    System.err.println(a.getX());
    System.out.println("43");
    }
    , Mar 7, 2006
    #13
  14. wrote:
    > Hello again,
    >
    > I added to "System.out" to your example and
    > ran it from IntelliJ IDEA...
    >
    > 41 appears in the color black at the console.
    > 0 appears in red
    > 43 appears in black.
    >
    > Can somebody explain me what is going on?
    > (I realize that 0 appears because it hasn't
    > been initialized, but how does the console
    > notice that?)
    >
    > class B {
    > public B(A a) {
    > System.out.println("41");
    > System.err.println(a.getX());

    ^^^
    > System.out.println("43");
    > }
    >

    its more likely that the console is showing the output was to std Err
    not std Out.
    Andrew McDonagh, Mar 7, 2006
    #14
  15. wrote:
    >
    > can you show me an example of how the following field could
    > be exposed to an external viewer before the object being
    > constructed ?
    >
    > How could any external viewer access a private instance field
    > before having a reference to the object ?



    public class A {
    private final int x;
    A() {
    new B(this);
    this.x = 42;
    }
    public int getX() {
    return x;
    }
    }

    public class B {
    public B(A a) {
    System.err.println(a.getX();
    }
    }

    The this need not be explicit. Anonymous inner classes have an implicit
    reference to the outer this, and are often created and released in
    constructors.

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
    Thomas Hawtin, Mar 7, 2006
    #15
  16. Roedy Green

    Guest

    > > System.out.println("41");
    > > System.err.println(a.getX());

    > ^^^
    > > System.out.println("43");
    > > }
    > >

    > its more likely that the console is showing the output was to std Err
    > not std Out.


    :)

    indeed!
    , Mar 7, 2006
    #16
  17. Roedy Green

    Roedy Green Guest

    On 7 Mar 2006 11:27:58 -0800, wrote, quoted or
    indirectly quoted someone who said :

    >41 appears in the color black at the console.
    >0 appears in red
    >43 appears in black.


    Eclipse does the same thing.
    System.err is red, System.out is black.
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
    Roedy Green, Mar 7, 2006
    #17
  18. wrote:
    > Stefan Schulz wrote:
    > > Be careful, though, in both cases the field may be exposed to external
    > > viewers before being assigned, and this will have the most undesirable
    > > effect of having the "final" value change.

    >
    > Hi,
    >
    > can you show me an example of how the following field could
    > be exposed to an external viewer before the object being
    > constructed ?
    >
    > How could any external viewer access a private instance field
    > before having a reference to the object ?


    static field:

    class A1 {
    private static final A1 instance;

    static {
    instance = new A1(new B1());
    }

    public static A1 getInstance(){
    return instance;
    }

    /* ... */
    }

    class B1 {
    public B1(){
    A1 foo = A1.getInstance(); // <--- will return 0
    /* ... */
    }

    /* ... */
    }

    non-static:

    interface Priority {
    int getPriority();
    }

    class A2 implements Priority {
    private static PriorityList list = new PirorityList();

    private final int priority;

    public A2(int priority){
    list.add(this);

    this.priority = priority;
    }

    public int getPriority(){
    return priority;
    }
    }

    class PriorityList implements List<Priority> {
    /* ... */

    public boolean add(Priority a){ /* inserts at priority position */
    int prio = a.getPriority(); // <--- will return 0

    /* ... */
    }
    }
    Stefan Schulz, Mar 8, 2006
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roedy Green

    Toward more efficient ArrayLists

    Roedy Green, Jun 28, 2003, in forum: Java
    Replies:
    10
    Views:
    1,483
    Jon Skeet
    Jul 3, 2003
  2. antoine
    Replies:
    1
    Views:
    376
  3. Victor
    Replies:
    0
    Views:
    470
    Victor
    Jun 8, 2004
  4. Sea Squid
    Replies:
    3
    Views:
    534
    Sea Squid
    Mar 17, 2005
  5. Roedy Green

    Toward more ruly background apps

    Roedy Green, Nov 24, 2011, in forum: Java
    Replies:
    10
    Views:
    419
    Roedy Green
    Nov 30, 2011
Loading...

Share This Page