Is final necessary in this case

205 views
Skip to first unread message

tm jee

unread,
Jan 22, 2014, 8:29:29 PM1/22/14
to mechanica...@googlegroups.com
Hello guys, 

if we have this bit of code

public void doSomething() {
   Thread[] threads = new Thread[10];
   for (int a=0; a< threads.length; a++) {
      threads[a] = new Thread(new MyRunnable(a));
   }
}

public class MyRunnable {
  private final int a;
  public MyRunnable(** final ** int a) {
     this.a = a; 
  }
}


Is it really necessary to mark the int a in MyRunnable as final? It's not being shared by any other threads. Primitives are passed by value.

It seems like programmers these days are marking all fields and all methods as finals ... Am i missing something?

Any thoughts?

TIA.



Jonathan Yu

unread,
Jan 22, 2014, 9:24:20 PM1/22/14
to mechanica...@googlegroups.com
Hi,

As pointed out in a different thread, final has no impact on
performance. It's only used to communicate to other people looking at
your code that you don't intend to change that variable in the given
scope.

For the class variable 'a', final is a useful keyword, as it means
that only the constructor can change its value.

For the constructor, the final is probably not needed, since the
constructor will tend to be short. People might add that just to be
visually similar to other methods, I guess. The final keyword doesn't
matter outside of the method definition; in other words:

public void method(final int xx)

is the same as

public void method(int yy)

inside the caller. It is therefore different from C++'s const keyword
on methods, which is used to indicate that the method doesn't mutate
state.

Using the final keyword on long methods might be useful, as it won't
let the variable get changed anywhere inside the method.

public void method(final int yy)
{
...
...
yy = 100; // compile error
}

It's a convention for communicating intent to other humans, not for the JVM.

Cheers,

Jonathan
> --
> You received this message because you are subscribed to the Google Groups
> "mechanical-sympathy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mechanical-symp...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Konrad Malawski

unread,
Jan 22, 2014, 9:47:38 PM1/22/14
to mechanica...@googlegroups.com
Hey there,
Seems I took too long to compose my response, oh well...
+1 to Jonathan, but might as well follow up with quirky details, since I spent a bit double checking this :-)

* parameters and method local variables are allocated on the stack (not heap) anyway, 
  and each thread as it’s own part of the stack ("stack frame”), so there’s no room for “across threads stuff”.

* final in method parameters does not influence the generated bytecode in any way; 
  since the jvm doesn’t get the info, it has no clue if your code had final there or not.
  For fields that info is actually kept in the class file and could be used.

Final fields have been discussed a lot over, but I assume you’re asking more about the ** ** highlighted final parameter.

-- 
Konrad

tm jee

unread,
Jan 22, 2014, 9:59:53 PM1/22/14
to mechanica...@googlegroups.com
Thanks, it's clear to me now guys.

> Final fields have been discussed a lot over
one more reason to keep an eye to this mailing list.
 

Konrad, you mentioned that parameter and local variables are stored in the stack frame, is this similar to the registers (which is the nearest to a CPU execution unit)? or is it something different altogether?

Cheers.
To unsubscribe from this group and stop receiving emails from it, send an email to mechanical-sympathy+unsub...@googlegroups.com.

Konrad Malawski

unread,
Jan 22, 2014, 10:08:30 PM1/22/14
to mechanica...@googlegroups.com
The Stack refers to the JVM being a stack based machine (http://en.wikipedia.org/wiki/Stack-oriented_programming_language).

The StackFrame is itself “internals”, but actually has a nice javadoc page explaining what it is:

-- 
Konrad

Jonathan Yu

unread,
Jan 22, 2014, 10:27:37 PM1/22/14
to mechanica...@googlegroups.com
On Wed, Jan 22, 2014 at 9:47 PM, Konrad Malawski <kto...@gmail.com> wrote:
> For fields that info is actually kept in the class file and could be used.

This is interesting, I didn't know that! I learn a lot reading this list :-)

What sorts of stuff could a Sufficiently Sophisticated JVM do with
that information?

I thought that final stuff wasn't really guaranteed to be final, since
you could use Reflection to change a final field to non-final, and
then update it. I guess in that case, though, the JVM could undo
whatever optimizations it has done (e.g. inlining) after assuming that
the value was final.

Cheers,

Jonathan

Michael Barker

unread,
Jan 22, 2014, 10:47:13 PM1/22/14
to mechanica...@googlegroups.com
Cliff Click did a couple of long blog posts on the subject (during his tenure at Azul):


The upshot is the JVM could do a bunch of useful optimisations if a number of frameworks did do evil things like reflectively modifying final fields.

Mike.



Konrad Malawski

unread,
Jan 22, 2014, 10:51:41 PM1/22/14
to mechanica...@googlegroups.com
Easily verifiable by yourself by hexdumping a class file (private final == 0x0012) :-)

There are far smarter people than me on this list who might tell stories about what current JVMs can do with this, 
I’ll refrain myself from guessing around but can redirect that nice (though old) post around that topic: http://www.azulsystems.com/blog/cliff/2011-10-27-final-fields-part-2.

-- 
Konrad

Kirk Pepperdine

unread,
Jan 23, 2014, 3:04:03 AM1/23/14
to mechanica...@googlegroups.com
Hi,

Tthe keyword final is only used by javacc and it has no effect on the byte code or what can happen in the run time. In fact there is a thread running in hotspot-dev which I’ll paste into this message.

no, it's an urban myth.
You can test it by yourself, if you declare a local variable final or
not the exact same bytecode is produced by javac. The keyword final for
a local variable (or a parameter) is not stored in the bytecode.

BTW, final was introduced in 1.1 mostly to allow to capture the value of
a variable to be used by an anonymous class, Java 8 doesn't require this
kind of variable to be declared final anymore.


Kirk Pepperdine

unread,
Jan 23, 2014, 4:35:41 AM1/23/14
to mechanica...@googlegroups.com
As safe optimizing engine where values can be changed by reflection couldn’t know when a value maybe changed and therefore couldn’t apply certain optimizations such as register hoisting or unboxing. Generally the unsafe optimizations have to be protected with a trap so that they can be rolled back.

Regards,
Kirk

Gil Tene

unread,
Jan 23, 2014, 9:59:15 AM1/23/14
to mechanica...@googlegroups.com
There are multiple questions here (about the use if "final"):

Question 1: Does the final keyword in the method parameter declaration make a difference?

A: As other noted, the keyword (for method field declaration, or for local variable) makes no difference for code execution. It is useful for readability and making intent clear. But it is more than useless syntactic sugar: it's most important feature (and the reason you see it used a lot) is that it helps avoid multiple common coding mistakes. Like this one:

Class C {
  long importantValue;

  C(long importantValue) {
     ...
     importantValue = importantValue;
  }
}

The above code contains an often-seen bug which is unfortunately easy to accidentally create and easy to miss. The bug can be fixed either by changing the name of the method variable (which breaks the intuitive reading of the code), or by changing the assignment to say:
    this.importantValue = importantValue;

The value of declaring all method variables final (as a discipline) in this case is that it makes it impossible to code the commonly seen bug above, and forces you to choose a solution. Declaring variables (whether parameters or local) also helps avoid other common logic bugs that often pop up over the maintanence lifetime of code, in which variables are changed mid-method in ways that surprise people and contradict the original intent. 

Question 2: "It seems like programmers these days are marking all fields and all methods as finals... .. Am i missing something?

A: I think you meant "... all fields OF all method as finals", right? Marking methods final has a very different meaning, and should only be done if the intent is to limit extension and overrides by subclasses. There are valid places to do that, but there is NO reason to do it by default (without that clear design choice for the specific method), as it can limit the code's long term usefulness.

[Implicit, discussed in the thread] Question 3: Does "final" make a performance difference?
 
A: The answer differs depending on where "final" is used:

- For variables (method parameters and local variables): No, "final" makes no difference to performance whatsoever.

- For methods: No (on virtually all modern JVMs). While you'll find some very old performance tips telling people to declare methods final to reduce their call overhead and improve their chances of being inlined, this advice stopped being true in the late 1990s. All modern JVMs will apply "CHA" (Class Hierarchy Analysis), which is used to *prove* the effective finality of a method when it has exactly one implementor in the currently loaded code. As a result, methods that are not declared as final (but have not been overridden by a subclass) have exactly the same performance behavior as a final method. This includes the ability to use a "static" (as opposed to "virtual") dispatch when calling it, and the ability to safely inline the method in calling code without involving runtime checks or guards. The easiest example for this can be seen with getter and setter methods: they do not need to be declared final, and they are typically inlined such that they translate to a single instruction in the generated code, making the clean encapsulation just as fast as public field access would be, and keeping the code nicely extensible without a performance penalty.

- For static fields: Yes (on virtually all current JVMs). A static final field will be forced to be initialized before code that depends on the class in question is JIT'ed. The knowledge that the static final field will never change again is used by various optimizations to produce much faster code (mostly through constant propagation and resulting dead code elimination). This is highly beneficial and is often used to provide free (in runtime cost) configurability for code behavior (like turning asserts on or off).

- For instance fields: It depends (may become more or less performance-effecting in the mid-term future): The knowledge that an instance field is final can be used to support various very useful optimizations. Most of those relate to the ability to freely move reads of the known-to-be-final field across ordering barriers in a program, which in turn allows the elimination of field reads (including things like hoisting them out of loops), and potential other optimizations. However, since in practice instance fields are often re-written after initial object construction (e.g. in deserialization, and via reflection), optimizations that assume that "final" actually means final are potentially dangerous, and are therefore avoided in most current JVMs. This may change in the future in various ways: On the one hand, runtime work to "prove" (or safely speculate and recover when wrong) that final fields are actually final can help expose those optimizations, which would make declared final fields provide better performance. On the other hand, the same sort of logic could be used to prove the "effective finality" of fields that are not declared final (much like CHA does for methods), in which case explicit final declarations will not provide a performance difference.

tm jee

unread,
Jan 23, 2014, 11:38:59 PM1/23/14
to mechanica...@googlegroups.com
Thanks for the detailed reply Gil & friends.

Static field by itself do not guarantee that it is thread safe (visible to other threads) but if marked together with final, will always do a StoreStore and make sure it is visible to other threads as well. Is this statement correct?

Gil Tene

unread,
Jan 24, 2014, 1:38:03 AM1/24/14
to <mechanical-sympathy@googlegroups.com>
On Jan 23, 2014, at 8:38 PM, tm jee <tmj...@gmail.com> wrote:

Static field by itself do not guarantee that it is thread safe (visible to other threads) but if marked together with final, will always do a StoreStore and make sure it is visible to other threads as well. Is this statement correct?

Sort of. A truly final field is by-definition thread-safe: it has exactly one valid readable value.

Final fields are guaranteed to be visible only in their final, initialized-by-the-constructor-form to all threads. In practice, there is a guaranteed StoreStore barrier between the final field initialization and the publication (storing into a shared location readable by other threads) of the reference to the newly constructed object, which means that the object reference cannot become visible before the final field value is.

However, these rules only apply as long as the final field is not somehow manipulated (by your code or code that you call) in a way that overrides it's finality. Using Reflection with java.lang.reflect.Field.setAccesible() , you can override and write into a final field. This is often done in de-serialization code, but could happen anywhere else. If/When final fields are written to after the initializing store, all final field qualities are out the window, and you are looking at a regular mutable field with all related races being possible.


sorin cristea

unread,
Jan 25, 2014, 2:20:32 PM1/25/14
to mechanica...@googlegroups.com
Hi Gil,

  from what I read before a global static field it's not thread safe, even if it's not declared final ? 

  in the bellow code example , the initialization that is make on static block it's always thread safe and all threads will see the same value for count variable( count = 5), even if all threads share the same reference to the class B, objB, here I don't need to have some final filed in order to make field visible to all threads, right ? Do you have in mind one example when a global static filed is not thread safe ?

 class A {
     private B objB = new B();

      private Runnable task(){
           return new Runnable(){
          
               public void run(){
                     objB.someMethodB();
               }
           };

      }
    
     public static void main(a ...){
         for(int i = 0 ; i < 5 ; i++){
             new Thread(task()).start();
          }
     }
 }

 class B {
      private static int count ;
   
    static {
      count = 5 ;
    }

    public void someMethodB(){
           count ++ ;
           System.out.println(String.format("value of count: %d", count)
    }
    .....
 }


 Thanks
 Sorin.

Gil Tene

unread,
Jan 26, 2014, 2:25:39 PM1/26/14
to <mechanical-sympathy@googlegroups.com>
The initialization code for the class will execute before any access to it would, so the *initial* values of A.objB and B.count do not have any ordering problems. However, since the fields are not final, their value can be changed later, after initialization, and any such change will need to be synchronized in some way to be consistently visible across threads.

The other (very big) thing you lose by not having the static fields below declared final is that the JIT compiler (at least with current techniques used in JVMs) cannot treat their value as constant. This removes many optimizations that would be possible if the value were known to be a constant, including a lot of speed that can come from dead-code elimination.

-- 
You received this message because you are subscribed to a topic in the Google Groups "mechanical-sympathy" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mechanical-sympathy/GVOlGyBQj-s/unsubscribe.
To unsubscribe from this group and all of its topics, send an email to mechanical-symp...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages