Results 1 to 16 of 16
  1. #1
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Why the arguments must be final to an anonymous class ?

    From Thinking in JAVA:

    If youíre defining an anonymous inner class and want to use an object thatís defined outside the anonymous inner class, the compiler requires that the argument reference be final, as you see in the argument to destination( ). If you forget, youíll get a compile-time error message.
    Any logical reason ?

  2. #2
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default Re: Why the arguments must be final to an anonymous class ?

    Roedy Green's execellent page on Nested Classes has this to say:

    "The rule is anonymous inner classes may only access final local variables of the enclosing method. Why? Because the inner class’s methods may be invoked later, long after the method that spawned it has terminated, e.g. by an AWT (Advanced Windowing Toolkit) event. The local variables are long gone. The anonymous class then must work with flash frozen copies of just the ones it needs squirreled away covertly by the compiler in the anonymous inner class object.

    "You might ask, why do the local variables have to be final? Could not the compiler just as well take a copy of non-final local variables, much the way it does for a non-final parameters? If it did so, you would have two copies of the variable. Each could change independently, much like caller and callee’s copy of a parameter, however you would use the same syntax to access either copy. This would be confusing. So Sun insisted the local be final. This makes irrelevant that there are actually two copies of it.

    "The ability for an anonymous class to access the caller’s final local variables is really just syntactic sugar for automatically passing in some local variables as extra constructor parameters. The whole thing smells to me of diluted eau de kludge."

  3. #3
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    25

  4. #4
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Why the arguments must be final to an anonymous class ?

    @Fubarable:

    From the link you provided:

    according to the specifications on local inner classes methods we must declare the variables as final or else it will result in a compile time error.
    So the rule of passing FINAL variables only is for: local classes but not for anonymous classes? Am I right ?

    Does not matter if my local class is anonymous or has a name, all the arguments passed to a LOCAL inner class must be FINAL ?

  5. #5
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    25

    Default Re: Why the arguments must be final to an anonymous class ?

    Quote Originally Posted by fatabass View Post
    So the rule of passing FINAL variables only is for: local classes but not for anonymous classes? Am I right ?
    No these rules are for anonymous inner classes. What is a local non-anonymous inner class?


    Does not matter if my local class is anonymous or has a name, all the arguments passed to a LOCAL inner class must be FINAL ?
    You've lost me here. AFAIK only anonymous inner classes can be defined inside of a method.

  6. #6
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Why the arguments must be final to an anonymous class ?

    Well I did not know that..

    So a class defined in a method(or a constructor) is called an inner class and HAS to be anonymous..

    Sorry, I am a beginner and JAVA really makes my headspin.
    Last edited by fatabass; 02-04-2012 at 11:06 PM. Reason: not (or a class)! changed to: (or a constructor)

  7. #7
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    25

    Default Re: Why the arguments must be final to an anonymous class ?

    Hang on, I may be wrong here...

  8. #8
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Why the arguments must be final to an anonymous class ?

    Yeah I was just going to post this:

    Java Code:
    public class LocalInnerClassTest {
    	public void defineInnerClass(final int var) {
    		class MyLocalInnerClass {
    			public void doSomething() {
    				System.out.println(var);
    			}
    		}
    	}
    }
    I was about to commit a suicide..

  9. #9
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default Re: Why the arguments must be final to an anonymous class ?

    Java Code:
    public class NamedLocal {
        public static void main(String[] args) {
            class XYZ {
                void foo() {
                    System.out.println("Works for me!");
                }
            };
            XYZ xyz = new XYZ();
            xyz.foo();
        }
    }

  10. #10
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    25

    Default Re: Why the arguments must be final to an anonymous class ?

    Yep (again), I'm wrong. Maybe I'll delete my embarrassing posts later.

  11. #11
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Why the arguments must be final to an anonymous class ?

    So.. both @Fubarable and @pbrockway2

    So the rule of passing FINAL variables only is for: local classes but not for anonymous classes? Am I right ?

    Does not matter if my local class is anonymous or has a name, all the arguments passed to a LOCAL inner class must be FINAL ?

  12. #12
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Why the arguments must be final to an anonymous class ?

    I will answer my own question:


    The Method Local Inner class, as the name specifies is local to a method. It implies that the method local Inner class is defined inside a method of a class. As the class is defined inside a method, it needs to be instantiated from with in the same method, but after the class definition is finished. As a mater of fact this inner class cannot use the variables of the same method, unless they are declared final.

    source: Java Tutorial Online: Method Local Inner Class in Java

    So: YES, All anonymous classes are local classes, and yes all local classes require FINAL variables.

  13. #13
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default Re: Why the arguments must be final to an anonymous class ?

    Quote Originally Posted by fatabass View Post
    So.. both @Fubarable and @pbrockway2

    So the rule of passing FINAL variables only is for: local classes but not for anonymous classes? Am I right ?
    Yes, classes which are not local have access to all the (possibly changing) state of the enclosing class. The fact that they're anonymous doesn't alter that.

    Java Code:
    public class ClassesAnonymous {
        int val = 42;
        
        Printer valPrinter = new Printer() {
            public void print() {
                System.out.println(val);
            }
        };
        
        public static void main(String[] args) {
            ClassesAnonymous test = new ClassesAnonymous();
            test.valPrinter.print();
          
            test.val = 666;
            test.valPrinter.print();
        }
    }
    
    interface Printer {
        void print();
    }
    Does not matter if my local class is anonymous or has a name, all the arguments passed to a LOCAL inner class must be FINAL ?
    Yes, named local classes can only access things in the enclosing scope (method) if they are final.

    Java Code:
    public class NamedLocal {
        public static void main(String[] args) {
            final int val = 42;
                // named direct subclass of Object
            class XYZ {
                void foo() {
                    System.out.println(val);
                }
            };
            XYZ xyz = new XYZ();
            xyz.foo();
            
            /*
            val = 666;
            xyz.foo(); // what should be printed if val could change?
            */
        }
    }
    Again it makes no difference if the local class is anonymous

    Java Code:
    public class AnonLocal {
        public static void main(String[] args) {
            final int val = 42;
                // anonymous direct subclass of Object
            XYZ xyz = new XYZ() {
                public void foo() {
                    System.out.println(val);
                }
            };
            xyz.foo();
            
            /*
            val = 666;
            xyz.foo(); // what should be printed if val could change?
            */
        }
    }
    
    interface XYZ {
        void foo();
    }
    Last edited by pbrockway2; 02-04-2012 at 11:42 PM.

  14. #14
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Why the arguments must be final to an anonymous class ?

    @pbRock, thanks for the great examples.

    I am really not sure if this what I am posting is a question or just an addition but here is what I have done:

    Java Code:
    package myPackage;
    
    public class OuterClass 
    {
    	public int OuterClassInt;
    	
    	void print(final int SomeInt)
    	{
    		class LocalInnerClass
    		{
    			void foo()
    			{
    				System.out.println(OuterClassInt);
    				System.out.println(SomeInt);
    			}
    		}
    		
    		new LocalInnerClass().foo();
    	}
    
    	public static void main(String[] args)
    	{
    		OuterClass outerClassObject = new OuterClass();
    
    		outerClassObject.OuterClassInt = 25;
    		outerClassObject.print(outerClassObject.OuterClassInt);
    		
    		outerClassObject.OuterClassInt = 35;
    		outerClassObject.print(outerClassObject.OuterClassInt);
    	}
    }
    So actually I am passing an integer that is not final, I am just saying that this integer I am passing in the method argument is final, by marking it "final int" in the method argument..

    This is a little confusing, but I guess my brain will burn, so I will just stop here and accept it as it is for now.

  15. #15
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Why the arguments must be final to an anonymous class ?

    Also regarding your code:

    Java Code:
    public class AnonLocal {
        public static void main(String[] args) {
            final int val = 42;
                // anonymous direct subclass of Object
            XYZ xyz = new XYZ() {
                public void foo() {
                    System.out.println(val);
                }
            };
            xyz.foo();
             
            /*
            val = 666;
            xyz.foo(); // what should be printed if val could change?
            */
        }
    }
     
    interface XYZ {
        void foo();
    }
    Isn't it better to replace:
    // anonymous direct subclass of Object
    by:
    // anonymous direct subclass of Object implements interface XYZ ?

  16. #16
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default Re: Why the arguments must be final to an anonymous class ?

    Isn't it better to replace:
    // anonymous direct subclass of Object
    by:
    // anonymous direct subclass of Object implements interface XYZ ?
    The comment was just there as a reminder that the class involved was anonymous. But, yes, it implements interface XYZ.

    So actually I am passing an integer that is not final, I am just saying that this integer I am passing in the method argument is final, by marking it "final int" in the method argument..
    Remember that what is passed is a copy of the integer value. And, in general, it is variables that are final or not, not their values (integers etc).

    All that the local inner class cares about it that the variable SomeInt is final. It is going to use its value later and wants to be sure it won't change. It does not matter whether the value it gets comes from a variable or expression like outerClassObject.OuterClassInt that is not final.

    outerClassObject.OuterClassInt can change as often as it likes, but SomeInt must not change: and that is what declaring SomeInt as final means. When you call print() a second time you can pass it a different value. It will assign that value to a new SomeInt that again will be final. Putting "final" in the print() declaration means something like "this won't change for the life time of this method". After the method finishes the SomeInt disappears whether it is final or not.

Similar Threads

  1. Replies: 15
    Last Post: 02-04-2012, 11:15 PM
  2. Replies: 2
    Last Post: 05-01-2010, 08:59 AM
  3. Using final with method arguments
    By Java Tip in forum java.lang
    Replies: 0
    Last Post: 04-17-2008, 07:48 PM
  4. Name of Anonymous class
    By eva in forum New To Java
    Replies: 1
    Last Post: 12-31-2007, 01:07 PM
  5. Anonymous class
    By ravian in forum Advanced Java
    Replies: 3
    Last Post: 12-25-2007, 10:56 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •