• Post Reply Bookmark Topic Watch Topic
  • New Topic

local variable is accessed from within inner class; needs to be declared final  RSS feed

 
Piter Smith
Ranch Hand
Posts: 55
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How and where do I declare table so that it *can* be accessed from within the inner class?





 
Maneesh Godbole
Bartender
Posts: 11445
18
Android Eclipse IDE Google Web Toolkit Java Mac Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You need to declare it as a variable for your Simple class
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html

This is not really a UI question. Moving to a more appropriate forum
 
Campbell Ritchie
Marshal
Posts: 56584
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Standard problem with local variables and parameters used by a local class.
  • 1: You call the method
  • 2: The local variable/parameter has a value on the stack
  • 3: You create an object of the local class, and it goes on the heap
  • 4: The method returns
  • 5: the object needs the local variable, and it has been removed from the stack
  •  
    Campbell Ritchie
    Marshal
    Posts: 56584
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Try again:
  • 1: You call the method
  • 2: The local variable/parameter has a value on the stack
  • 3: You create an object of the local class, and it goes on the heap
  • 3½: The object copies the value of that local variable
  • 4: The method returns
  • 5: the object needs the local variable, and it available


  • But that might not work. What about this scenario?
  • 1: You call the method
  • 2: The local variable/parameter has a value on the stack
  • 3: You create an object of the local class, and it goes on the heap
  • 3½: The object copies the value of that local variable
  • 4: The method alters the value of the local variable
  • 5: the object needs the local variable, and there are now two copies with different values
  • again!
     
    Campbell Ritchie
    Marshal
    Posts: 56584
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    You can try going through the method with the compiler looking whether that local variable is changed, and if so, mirror the changes in the local object. But if you have tried writing a compiler, you know that will mean your one method takes as long to compile as the rest of the class, and that bit of the compiler takes longer to write than everything else put together.
    So you have to come up with a simple and reliable solution: make sure that local variable cannot be reassigned. And you do that with the keyword final.
     
    Campbell Ritchie
    Marshal
    Posts: 56584
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    This problem does not apply to fields of the outer class, because the lifetime of the local class is bound to the outer class, so whenever the local class object is present, there will be an instance of the outer class, so any fields will still be accessible.
     
    Piter Smith
    Ranch Hand
    Posts: 55
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    ok. I made those variables static to the outer class, but that just seems a bit odd. Oh well. Thank you for the help.
     
    Campbell Ritchie
    Marshal
    Posts: 56584
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I know it is late to reply, but making something static “because it works” almost always means you don’t understand what static means. you should simply have marked those local variables final.
     
    Piter Smith
    Ranch Hand
    Posts: 55
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Campbell Ritchie wrote:I know it is late to reply, but making something static “because it works” almost always means you don’t understand what static means. You should simply have marked those local variables final.


    Why should they be final? At least one of those objects cannot be final, so I don't see how that's a solution. It's no different from "well, it runs" which is what I did.

    To put another way, how do you access those objects from anonymous classes?
     
    Campbell Ritchie
    Marshal
    Posts: 56584
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I feel I am going round in circles here. They have to be final so they can safely be used by the local class. If you need to reassign anything (which you usually don’t), you will need two different variables which (initially) point to the same value/reference. If it is appropriate that the variable be a field of the instance, then it should be a field. But not static. If you are running code in a static context throughout, that is almost always a mistake. Even when your book or the Java™ Tutorials commit the same mistake.
     
    Steve Luke
    Bartender
    Posts: 4181
    22
    IntelliJ IDE Java Python
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Piter Smith wrote:
    Campbell Ritchie wrote:I know it is late to reply, but making something static “because it works” almost always means you don’t understand what static means. You should simply have marked those local variables final.


    Why should they be final?


    Because the value are local to the method, they could have a shorter live span than the Object in which you want to use them. By making the references final you are signalling that it is okay for those values to escape in an 'as-is' manner to be used for the longer life-span of the Object.

    Piter Smith wrote: At least one of those objects cannot be final, so I don't see how that's a solution.

    Actually not. You don't need to use the same reference to the DefaultTableModel. You create it in the method, assign it to the table, and never do anything else with that Object (the Object referred to by dtm). You then get another DefaultTableModel from the MessageController Object. You attempt to assign that reference to the same dtm variable, which you then pass on to the table, but again, still never refer to it again. So why event keep the variable around or try to use the same variable for what really is un-related model?

    This works just as well, and doesn't give the impression that you need that dtm reference for some reason. And if you did you could just use a new reference to the DefaultTableModel.
    Piter Smith wrote: It's no different from "well, it runs" which is what I did.

    It is quite different in the scope of things. when you make them static you are expanding the scope of the Objects well beyond where they are needed. This can lead to issues with understanding which Objects are being used, re-using Objects and their state when you don't expect to, re-assigning the Objects being referenced when you don't expect to, having Objects being referenced in inconsistent stated (for example if those references might get used by multiple threads)... You should not expand things beyond the local scope unless you absolutely need to.

    Piter Smith wrote: To put another way, how do you access those objects from anonymous classes?

    You can access them and even change the state of Object by using final variables to reference them. If you find the need to change the referenced value to something new it usually is a mistake (as shown above with dtm) or shows the need for a redesign (sometimes as simple as an Object to wrap the values in, but you don't need that in this case since the MessageController seems to already handle that).
     
    It is sorta covered in the JavaRanch Style Guide.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!