Hi,

> -----Original Message-----
> From: Konstantin Kolinko [mailto:knst.koli...@gmail.com]
> Sent: Tuesday, April 22, 2014 10:50 PM
> 
> 2014-04-23 0:43 GMT+04:00 Mark Thomas <ma...@apache.org>:

(snip)

> > No objection to the final being restored, it is good practice to use
> > final when possible.
> >
> > It isn't something that has been used much elsewhere in the Tomcat code
> > base. Is there much benefit to going through and adding it everywhere it
> > could be used? If I recall correctly, the UCDetector plugin can flag up
> > all the places where this can be done and probably add them as well.
> 
> I think that it does not change the generated byte code, thus no real
> difference.
> It is good from documentation point of view (to express you intention
> to do not change the variable).
> 
> If one goes pedantic way,  I have seen code where 'final' was added to
> all parameters of every method. I do not like that code style.

+1

I've once worked with a Java program at a company that used a code style tool 
issuing a warning for every local variable that did not change and was not 
declared as "final". The result was that for some method's code, you felt like 
the code consists only of "final" modifiers and it was harder to read.


AFAIK, the only two technical uses of "final" for method/local variables are:
1) If you assign a constant expression to a variable, the Eclipse and Oracle 
compiler will replace references to this variable with the constant expression. 
E.g., if you write:

    public static void someMethod(int x) {
        int i1 = 42;
        final int i2 = 42;
        System.out.println(i1);
        System.out.println(i2);
        
        int x1 = x;
        final int x2 = x;
        System.out.println(x1);
        System.out.println(x2);
    }

and compile it, then view the .class file with a decompiler, it will show:

  public static void someMethod(int x) {
    int i1 = 42;
    int i2 = 42;
    System.out.println(i1);
    System.out.println(42);
    
    int x1 = x;
    int x2 = x;
    System.out.println(x1);
    System.out.println(x2);
  }

So references to "i2" have been replaced with the constant expression by the 
compiler. This should also happen for class attributes that a "final" modifier 
and constant values.


2) If you want to use a local variable inside of an anonymous inner class. The 
compiler will have to make a copy of the variable when the anonymous class 
instance is created, as the variable is stored in the stack and will vanish 
once the outer method returns. I think the "final" probably would technically 
not be needed, but then if you changed the variable in the anonymous inner 
class' method, the change would not be reflected in the outer method.


For comparison, in .Net/C#, when you write an anonymous method inside of 
another method and the anonymous method accesses some variables of the outer 
method, the compiler will automatically change the code to store that set of 
variables in some wrapper object, and have the code working with that wrapper. 
That means if you change one of the variables in the anonymous method, the 
change will be reflected on the outer method.

Consequently, C# does have a "readonly" modifier to mark class/type attributes 
as read-only like the "final" in Java, but not for local variables. However, 
for constant values, it has the "const" modifier that can be used for both 
class-wide variables (which would be like using "static readonly") and local 
variables, so the compiler will replace those variable references with the 
constant values (and "const" variables will not take space on the stack or in 
an object).


Regards,
Konstantin Preißer


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to