Results 1 to 13 of 13

Thread: Final keyword

  1. #1
    Pino is offline Member
    Join Date
    Feb 2011
    Posts
    5
    Rep Power
    0

    Default Final keyword

    Hello!

    I have a small question about the 'final' keyword. I just now used it to solve a certain problem, but I'm not sure how it works (Eclipse told me to ).
    It's the following:
    In a constructor of a class, I loop through an enum with this: for(Direction dir : Direction.getValues()).
    In this loop, I create an instance of some other class for each direction. This instance overrides a method
    from its class, and uses the 'dir' value in this method.

    Now I've had to use the final modifier on 'dir'. But I don't really understand why. To be completely honest, my instinct told me what I was trying to do the way I was doing it was logically impossible. That's why I was completely stumped when the 'final' keyword actually solved it. Is this because the value is an enum?

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

    Default Re: Final keyword

    Now I've had to use the final modifier on 'dir'. But I don't really understand why.
    If you were using dir as an argument to some method and that method was declared to take a final argument, then you have to declare dir as final. If a method is declared to take an int[] argument, you must declare the argument as int[]: if it is declared to take final Direction, then final Direction it must be.

    If the method in question is not declared to take a final argument, or it is and you don't see why, post the relevant code (or documentation if this other class in a library).

  3. #3
    awinston is offline Student
    Join Date
    Jul 2012
    Location
    United States
    Posts
    328
    Rep Power
    3

    Default Re: Final keyword

    Quote Originally Posted by pbrockway2 View Post
    If you were using dir as an argument to some method and that method was declared to take a final argument, then you have to declare dir as final. If a method is declared to take an int[] argument, you must declare the argument as int[]: if it is declared to take final Direction, then final Direction it must be.

    If the method in question is not declared to take a final argument, or it is and you don't see why, post the relevant code (or documentation if this other class in a library).
    I didn't realize that a method could be declared to take in a final argument. Does this apply to accessibility descriptions such as 'public' and 'private' as well? It would be great if you could link to a tutorial if one exists.
    "Success is not final, failure is not fatal: it is the courage to continue that counts." - Winston Churchill

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

    Default Re: Final keyword

    No public/private only make sense for declarations of instance or class methods and variables. But final (== "I won't go changing this value") can occur anywhere including local variables and the parameters of methods.

    Not a tutorial, but Roedy Green discusses final in his Glossary.

    [Edit] Green declares himself a fan of final, but doesn't actually talk about final method parameters as such. They don't seem to occur much in the standard Java API (do they?) so I wouldn't use them.

    Java Code:
    // untested
    public void setMessage(String msg) {
        final String theMsg = msg;
        myButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println(theMsg);
            }
        });
    }
    In that code I could have declared the method as setMessage(final String msg) and done away with the other variable, but I don't think I would want to impose this requirement on the method's caller.
    Last edited by pbrockway2; 08-24-2012 at 12:04 AM.

  5. #5
    awinston is offline Student
    Join Date
    Jul 2012
    Location
    United States
    Posts
    328
    Rep Power
    3

    Default Re: Final keyword

    Quote Originally Posted by pbrockway2 View Post
    No public/private only make sense for declarations of instance or class methods and variables. But final (== "I won't go changing this value") can occur anywhere including local variables and the parameters of methods.

    Not a tutorial, but Roedy Green discusses final in his Glossary.

    [Edit] Green declares himself a fan of final, but doesn't actually talk about final method parameters as such. They don't seem to occur much in the standard Java API (do they?) so I wouldn't use them.

    Java Code:
    // untested
    public void setMessage(String msg) {
        final String theMsg = msg;
        myButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println(theMsg);
            }
        });
    }
    In that code I could have declared the method as setMessage(final String msg) and done away with the other variable, but I don't think I would want to impose this requirement on the method's caller.
    Okay, thank you. I thought you meant that a method could be declared like so:

    Java Code:
    public void setMessage(final String msg)
    {
       ...
    }
    "Success is not final, failure is not fatal: it is the courage to continue that counts." - Winston Churchill

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

    Default Re: Final keyword

    Quote Originally Posted by awinston View Post
    Okay, thank you. I thought you meant that a method could be declared like so:

    Java Code:
    public void setMessage(final String msg)
    {
       ...
    }
    Yes, he did mean that just that is possible and is used -- try it yourself, and you'll see that it compiles fine. Some recommend that most variables and parameters should be declared final unless you the coder are sure that they will need to be re-assigned within their scope.

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

    Default Re: Final keyword

    Yes, I meant that the alternative would compile.

    But forget what I said about marking the parameter as final as imposing any condition on the caller. Of course it doesn't. I don't know what I was thinking.

    Java Code:
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    
    public class Test {
        
        private JButton myButton;
        
        public void setMessage(final String msg) {
            // msg in this method is final
            // it has to be  to be used by actionPerformed()
            myButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.out.println(msg);
                }
            });
        }
        
        void foo() {
                // msg in this method is a different variable and need not be final
            String msg = "asd";
            setMessage(msg);
        }
    }

  8. #8
    awinston is offline Student
    Join Date
    Jul 2012
    Location
    United States
    Posts
    328
    Rep Power
    3

    Default Re: Final keyword

    Quote Originally Posted by pbrockway2 View Post
    Yes, I meant that the alternative would compile.

    But forget what I said about marking the parameter as final as imposing any condition on the caller. Of course it doesn't. I don't know what I was thinking.

    Java Code:
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    
    public class Test {
        
        private JButton myButton;
        
        public void setMessage(final String msg) {
            // msg in this method is final
            // it has to be  to be used by actionPerformed()
            myButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.out.println(msg);
                }
            });
        }
        
        void foo() {
                // msg in this method is a different variable and need not be final
            String msg = "asd";
            setMessage(msg);
        }
    }
    Okay, thanks pbrockway2 and Furarable. So in this example (please correct me if I am wrong): If "Hello!" is the argument of setMessage(), a final local variable named msg will hold the value of "Hello!".
    "Success is not final, failure is not fatal: it is the courage to continue that counts." - Winston Churchill

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

    Default Re: Final keyword

    Quote Originally Posted by awinston View Post
    Okay, thanks pbrockway2 and Furarable.
    You're welcome

    So in this example (please correct me if I am wrong): If "Hello!" is the argument of setMessage(), a final local variable named msg will hold the value of "Hello!".
    Yes, that is correct. It behaves no different from any other parameter other than once assigned it cannot be re-assigned.

  10. #10
    Pino is offline Member
    Join Date
    Feb 2011
    Posts
    5
    Rep Power
    0

    Default Re: Final keyword

    Well, thank you everyone for the input!

    Quote Originally Posted by pbrockway2 View Post
    If the method in question is not declared to take a final argument.
    I don't think it is. During the entire project I haven't had to use the final keyword anywhere yet, and I don't usually.
    Here's the constructor of my class where what I was talking about happened:

    Java Code:
    /**
    * Creates a new DirectionSelectDialog.
    */
    public DirectionSelectDialog()
    {
    	super(null);
    	setLocation(Game.DISPLAY.getWidth() / 2 - 48, Game.DISPLAY.getHeight() / 2 - 48);
    	setDimension(96, 96);
    	
    	for(final Direction dir : Direction.values())
    	{
    		Button btnDir = new Button(this)
    		{
    			@Override
    			public void activate()
    			{
    				buffer.setDirection(dir);
    				if(buffer.getType() == ActionType.ENGRAVE)
    					((GameScreen) Game.ACTIVESCREEN).requestString(buffer);
    				else
    					Campaign.getPlayer().execute(buffer);
    				getParent().hide();
    			}
    		};
    		btnDir.setLocation(43 + dir.getDeltaX() * 32, 43 + dir.getDeltaY() * 32);
    		btnDir.setDimension(10, 10);
    		btnDir.setImage(Campaign.getImage("BTN_DIR"));
    		addComponent(btnDir);
    	}
    }
    Fair warning: The buttons & the like you see here are NOT native java classes. I've written my own Button classes & such from scratch, to optimize for games and fullscreen drawing. Where I got the warning was at 'buffer.setDirection(dir)'; which is nothing more than a simple setter. Buffer is an instance of a simple class called GameAction, containing only getters and setters for its fields, one of them being a Direction.

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

    Default Re: Final keyword

    In that example dir has to be declared as final because it is used in the implementation of the activate() method. It is similar in that regard to the example I gave where the string argument had to be final because it was used within the actionPerformed() method.

    The idea is that you are promising not to change the value of dir within the for loop. And that allows an anonymous subclass of Button to be declared with a copy of the known value of dir being passed to the instance of the subclass of Button you create. Other languages don't have this restriction - eg JavaScript where variables in the scope of a function you are defining are part of the context of that function and can change. In Java, however, variables you "import" into a method in this way must be final.
    Last edited by pbrockway2; 08-28-2012 at 03:32 PM.

  12. #12
    Pino is offline Member
    Join Date
    Feb 2011
    Posts
    5
    Rep Power
    0

    Default Re: Final keyword

    That makes sense, thank you.

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

Similar Threads

  1. this keyword
    By coltragon in forum New To Java
    Replies: 10
    Last Post: 03-01-2010, 09:20 AM
  2. what is the use of final keyword
    By sumanandjesus in forum Advanced Java
    Replies: 9
    Last Post: 03-27-2009, 12:50 PM
  3. [SOLVED] is final class members are also final ?
    By haoberoi in forum New To Java
    Replies: 4
    Last Post: 11-10-2008, 03:01 PM
  4. Method with final keyword
    By javaplus in forum New To Java
    Replies: 2
    Last Post: 11-29-2007, 09:39 AM
  5. Use of this keyword
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 11-18-2007, 07:32 PM

Tags for this Thread

Posting Permissions

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