Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / March 2006

Tip: Looking for answers? Try searching our database.

Toward more extensive use of final

Thread view: 
Roedy Green - 07 Mar 2006 07:42 GMT
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;
}
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Stefan Schulz - 07 Mar 2006 08:22 GMT
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.
neuneudr@yahoo.fr - 07 Mar 2006 18:32 GMT
> 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;
>}
Thomas Hawtin - 07 Mar 2006 19:10 GMT
> 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
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

neuneudr@yahoo.fr - 07 Mar 2006 19:16 GMT
> public class A {
>      private final int x;
[quoted text clipped - 12 lines]
>      }
> }

thanks!
neuneudr@yahoo.fr - 07 Mar 2006 19:27 GMT
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");
    }
Andrew McDonagh - 07 Mar 2006 19:30 GMT
> Hello again,
>
[quoted text clipped - 14 lines]
>          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.
neuneudr@yahoo.fr - 07 Mar 2006 19:43 GMT
> >          System.out.println("41");
> >          System.err.println(a.getX());
[quoted text clipped - 4 lines]
> its more likely that the console is showing the output was to std Err
> not std Out.

:)

indeed!
Roedy Green - 07 Mar 2006 22:44 GMT
>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.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Stefan Schulz - 08 Mar 2006 11:40 GMT
> > Be careful, though, in both cases the field may be exposed to external
> > viewers before being assigned, and this will have the most undesirable
[quoted text clipped - 8 lines]
> 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

     /* ... */
  }
}
Jacob - 07 Mar 2006 08:28 GMT
> 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;
  }
Thomas Hawtin - 07 Mar 2006 09:55 GMT
> 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
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

jagonzal@gmail.com - 07 Mar 2006 12:44 GMT
> 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)
tom fredriksen - 07 Mar 2006 15:36 GMT
>> private static final  int x;
>>
[quoted text clipped - 8 lines]
> 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
Ingo R. Homann - 07 Mar 2006 17:04 GMT
Hi,

>>> private static final  int x;
>>>
[quoted text clipped - 10 lines]
>
> 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
tom fredriksen - 07 Mar 2006 15:52 GMT
> 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
[quoted text clipped - 24 lines]
>  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
Roedy Green - 07 Mar 2006 17:19 GMT
>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.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

neuneudr@yahoo.fr - 07 Mar 2006 18:24 GMT
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


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.