aspose file tools*
The moose likes Beginning Java and the fly likes About annonymous classes and the final keyword Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Java 8 in Action this week in the Java 8 forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "About annonymous classes and the final keyword" Watch "About annonymous classes and the final keyword" New topic
Author

About annonymous classes and the final keyword

Ronald Castillo
Ranch Hand

Joined: Apr 16, 2011
Posts: 47

Reading thru one of my books I've stumbled upon the following:

Followed by this:
If you need to access variables in your annonymous class from the enclosing class, those variables must be final.


Why is that? Why do I need to declare the variables final so my annonymous class can call the cancel method on it? Why can't I do it directly w/o declaring it as final?
Ogeh Ikem
Ranch Hand

Joined: May 13, 2002
Posts: 180
At compile time, the compiler generates 2 classes



Because an inner class possesses the implicit this reference, it can directly access instance variables of its outer class. However, there is no way for an inner class to directly access local variables of its outer class. How should the JVM pass a local variable declared in one class file to another class file?

In order to solve this problem, the JVM makes a requirement for the developer to declare the local variable as final.

The compiler then places a hidden variable with the name val$timer inside the byte code for outclass$anonymousinnerclass.class

The variable val$timer is assigned the same value as the final local variable timer

Because a variable declaration in one class is replicated in another class, both declarations must be the same i.e. both declarations must reference the same object. The final keyword is used to guarantee this.


Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19557
    
  16

And to prove this, let's create a short class, compile it and decompile it with JAD. The class:
This produces classes Test and Test$1 - the latter is the anonymous inner class. Decompiling the latter only shows this:
Note that there is actually a bug in there - the call to super() on line 22 should come before line 21, not after.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Suhrid Karthik
Ranch Hand

Joined: Aug 31, 2008
Posts: 58

Ogeh Ikem wrote:At compile time, the compiler generates 2 classes



Because an inner class possesses the implicit this reference, it can directly access instance variables of its outer class. However, there is no way for an inner class to directly access local variables of its outer class. How should the JVM pass a local variable declared in one class file to another class file?

In order to solve this problem, the JVM makes a requirement for the developer to declare the local variable as final.

The compiler then places a hidden variable with the name val$timer inside the byte code for outclass$anonymousinnerclass.class

The variable val$timer is assigned the same value as the final local variable timer

Because a variable declaration in one class is replicated in another class, both declarations must be the same i.e. both declarations must reference the same object. The final keyword is used to guarantee this.




I've been looking for a good explanation for this behaviour and yours is the best I've come across. Thank you !
Ogeh Ikem
Ranch Hand

Joined: May 13, 2002
Posts: 180
You're welcome.
Marco Terzuoli
Greenhorn

Joined: Oct 26, 2011
Posts: 2
You may also want to look here towards the end for some additional explanation on top of the one already given. https://sites.google.com/site/javadvanced/final-keyword
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36599
    
  16
Welcome to the Ranch

I am not sure I agree with everything in that link, however. For example, they say making methods final makes them difficult to maintain, and making all fields final makes an object immutable.
Marco Terzuoli
Greenhorn

Joined: Oct 26, 2011
Posts: 2
Campbell Ritchie wrote:Welcome to the Ranch

I am not sure I agree with everything in that link, however. For example, they say making methods final makes them difficult to maintain, and making all fields final makes an object immutable.


As I understand it, it says that making all fields final and pointing to immutable objects makes it immutable.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36599
    
  16
But that is not all you have to do to make an object immutable. You have to make the class final as well. Otherwise somebody can subclass that class with mutable fields. Then instances of that “immutable” class become mutable. Look at classes like java.lang.String, java.lang.Integer and java.math.BigDecimal. They are described as immutable, and they are all declared final.
You can have immutable objects whose fields are mutable; you need to return defensive copies of those fields in all the getXXX methods, to make sure those mutable fields cannot have their state changed.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3401
    
    9
I kinda disagree on making the object final. Sure enough, if you were to have a MyString that extends String, MyString itself could be mutable. But the String part of its type could still be immutable if all its fields are properly hidden and all its methods are final.

In such a case, it really wouldn't matter if you used a MyString where a String is expected, because there's nothing MyString can do about the immutable interface that String exports.

Of course it *still* is better to just make the class final and be done with it :p
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36599
    
  16
Stephan van Hulst wrote: . . . there's nothing MyString can do about the immutable interface that String exports. . . .
Except return a different hash code, different toString(), different results from equals() . . .
You use it as a “K” in a Map, thinking it is immutable, and its hash code changes and

As I said, you can make an immutable class whose fields are mutable, if you are careful not to allow those fields to be changed. You can even get away without labelling those fields final. But final makes it a lot easier. I think we are mostly in agreement.
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 2970
    
    9
Campbell Ritchie wrote:
Stephan van Hulst wrote: . . . there's nothing MyString can do about the immutable interface that String exports. . . .
Except return a different hash code, different toString(), different results from equals() . . .
You use it as a “K” in a Map, thinking it is immutable, and its hash code changes and

Well, Stephan did say "if all its fields are properly hidden and all its methods are final". That would prevent any of the method changes you're talking about.

This also assumes a class doesn't do anything to funky, like say rely on reflection to generate equals(), hashCode(), or toString() using all member variables of the current class.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: About annonymous classes and the final keyword
 
Similar Threads
sonir, read pls
passing an instance of Thread rather than Runnable to new Thread instance
enthuware question doubt and smth else
Anonymous class question
What is this method doing?