Inaccessible with local variable(non-final) via method local inner class

Hi All,
Usually local variables, including automatic final variable live on the stack and objects & instanace variables live on the heap.The contracts for using the method local inner class should allow merely method final variable, not non-final stack variable.
Can anyone please clarify me ,behind the scene what is actual fact why method inner class should not access the stack(method) variable and only allow final variable?
Is anything correlated with the stack and heap aspects?
Thanks,
Stalin.G

[email protected] wrote:
...behind the scene what is actual fact why method inner class should not access the stack(method) variable and only allow final variable?...explained by dcminter and Jardium in [an older thread|http://forums.sun.com/thread.jspa?messageID=10694240#10694240|http://forums.sun.com/thread.jspa?messageID=10694240#10694240]:
...Final variables are copied into inner classes - that's why they have to be declared final; to avoid the developer making an incorrect assumption that the local variable can be modified and have the change reflected in the copy.
When a local class uses a local variable, it doesn't actually use the variable. Instead, it takes a copy of the value which is contained in the variable at the moment the class is instantiated. It's like passing the variable to a constructor of the class, except that you do not actually declare any such constructor in your code.
To avoid messy execution flows to be present in a Java method, the Java language authors thought it was better to allow a single value to be present in such a variable throughout all its life. Thus, the variable has to be declared final.
...HTH

Similar Messages

  • Why method local inner class can use final variable rather than....

    Hi all
    Just a quick question.
    Why method-local inner class can access final variable defined in method only?
    I know the reason why it can not access instance variable in method.
    Just can not figure out why??
    any reply would be appreciated.
    Steven

    Local classes can most definitely reference instance variables. The reason they cannot reference non final local variables is because the local class instance can remain in memory after the method returns. When the method returns the local variables go out of scope, so a copy of them is needed. If the variables weren't final then the copy of the variable in the method could change, while the copy in the local class didn't, so they'd be out of synch.

  • Method local Inner class

    Why method local class can access only the final varaible of the method?
    I found somewhere that this is because the non-final local variables go out of scope after method completion, but i wonder final local variables also reside on the stack.
    class MyOuter2 {
    private String x = "Outer2";
    void doStuff() {
    String z = "local variable";
    class MyInner {
    public void seeOuter() {
    System.out.println("Outer x is " + x);
    System.out.println("Local variable z is " + z); // Won't Compile!
    } // close inner class method
    } // close inner class definition
    } // close outer class method doStuff()
    }

    pxNet wrote:
    and so you are now saying it accesses the original variable, not a copy of it?No, I'm not saying that at all; see reply #1. The situation is quite the opposite, the inner class accesses a copy of the variable. Direct access to the local variable is most definitely not allowed. But that doesn't have anything to do with parameter-passing semantics.
    I'll try to clarify with another demonstration of the problem. Assume that direct access to non-final local variables was actually allowed, and that the following example would compile (it won't, of course): class Outer {
        Inner method() {
            Object o = "foo";
            return new Inner() {
                public void modifyLocalVariable() {
                    o = "bar";
        interface Inner {
            void modifyLocalVariable();
        public static void main(String[] args) {
            Inner inner = new Outer().method();
            inner.modifyLocalVariable(); // what local variable is this modifying?
                                         // the local variable in method() has gone
                                         // out of scope!
    }Because of the way anonymous inner and local classes are implemented, they get a copy of the local variables (per the JLS). Mind you, there isn't any parameter passing going on at all in this example.
    ~

  • Method local Inner classes

    The local variables of the method live on the stack, and exist only for the lifetime of the method. You already know that the scope of a local variable is limited to the method the variable is declared in. When the method ends, the stack frame is blown away and the variable is history. But even after the method completes, the inner class object created within it might still be alive on the heap if, for example, a reference to it was passed into some other code and then stored in an instance variable. Because the local variables aren’t guaranteed to be alive as long as the method-local inner class object, the inner class object can’t use them. Unless the local variables are marked final! The following code attempts to access a local variable from within a method-local inner class.
    Can any one explaing me with an example of the above BOLDED text.

    Can any one explaing me with an example of the above BOLDED text
    class Outer {
         Outer outer;
         void method() {
              int i=0;
              class Local extends Outer {
                   int j = i;
              outer = new Local();
    }The above code doesn't compile unless the i variable in method() is declared final.

  • Local inner classes

    Hi all,
    Local inner classes can access all instance / static variables (include private) from enclosing class & local variables / methods parameters declared as final.
    class Outer {
    private int a = 0;
    static int b = 1;
    public void localInnerClassTest(final int k) {
    final double x = 0.4;
    class LocalInner {
    public void test() {
    System.out.println(a + " " + b + " " + k + " " + x);
    new LocalInner().test();
    public static void main(String args[]) {
    new Outer().localInnerClassTest(3);
    // shows 0 1 3 0.4
    I�ve seen in some mock exams that�s wrong ...
    Thankz

    Local inner classes can access all instance / static
    variables (include private) from enclosing class &
    local variables / methods parameters declared as
    final.Yes. That is correct
    >
    I�ve seen in some mock exams that�s wrong ...You've seen that what's wrong? - the statement you made above or the code you posted?
    The code you posted should not compile (is that what you mean by "wrong"), but you have not explained the problem you are having...
    Do you have a question you would like answered?

  • Local inner class

    *@author Rossi Kamal
    *version 1
    *easy local inner class
    public class local_inner
         final int Roll=10;
         public  void main(String args[])
              class _inner
                    int accountnumber=5;
                    int roll=Roll;
              _inner a=new _inner();
              System.out.println("Accoubtnumber"+a.accountnumber+"Roll"+a.roll);
    }

    Don't multi-post:
    http://forum.java.sun.com/thread.jspa?threadID=5130208&tstart=0

  • Why we are making a variable as final in method inner class ?

    Why we are making the variable as final (method inner class) while we are accessing the method variable in inner class ?
    regards,
    namanc

    As far as I can tell, the only reason is to protect the programmer: when the inner class instance is constructed, it is given the then-current value of the variable. If the variable (or method parameter) later changes, the value held by the inner class would not. By making the variable final, the programmer doesn't have to worry about them staying in sync.
    Here's some code to ponder:
    public class InnerExample
        void printMe( final int x )
            Runnable runMe = new Runnable()
                public void run()
                    System.out.println(x);
            (new Thread(runMe)).start();
    }When compiled with the Sun JDK 1.4.2, you get this bytecode:
    void printMe(int);
      Code:
       0:   new     #2; //class InnerExample$1
       3:   dup
       4:   aload_0
       5:   iload_1
       6:   invokespecial   #3; //Method InnerExample$1."<init>":(LInnerExample;I)V
       9:   astore_2
       10:  new     #4; //class Thread
       13:  dup
       14:  aload_2
       15:  invokespecial   #5; //Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
       18:  invokevirtual   #6; //Method java/lang/Thread.start:()V
       21:  returnAt line (byte) 5, it loads the passed value onto the stack; at line 6, it invokes the inner class constructor (which is created by the compiler). Nothing in this sequence of code would prevent use of a non-final variable.

  • Why only final variables can be accessed in an inner class ?

    Variables declared in a method need to declared as final if they are to be accessed in an inner class which resides in that method. My question is...
    1. Why should i declare them as final ? What's the reason?
    2. If i declare them as final, could they be modified in inner class ? since final variables should not modify their value.

    (Got an error posting this, so I hope we don't end up with two...)
    But what if i want to change the final local variable within that method instead of within anonymous class.You can't. You can't change the value of a final variable.
    Should i use same thing like having another local variable as part of method and initializing it with the final local variable?You could do. But as in the first example I posted you are changing the value of the nonfinal variable not the final one. Because final variables can't be changed.
    If so, don't you think it is redundant to have so many local variables for so many final local variables just to change them within that method?If you are worried that a variable might be redundant, don't create it. If you must create it to meet some need then it's not redundant.
    Or is there any alternate way?Any alternate way to do what?

  • Local variable can't be accessed from inner class ???????? Why ??????

    Plesae help, help, help. I have no idea what to do with this bug.........
    <code>
    for ( int i = 0; i <= 2; i++ ) {
    for ( int j = 0; j <= 2; j++ ) {
    grids[i][j] = new MyButton ();
    grids[i][j].setBorder(but);
    getContentPane().add(grids[i][j]);
    MyButton sub = grids[i][j];
    sub.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    if ( sub.getState() == 0 ) {
         sub = new MyButton( (Icon) new ImageIcon(imageFile));
         if ( imageFile.equals("cross.jpg") ) {
              sub.changeState(1);
         else {
              sub.changeState(2);
    </code>
    The compiler complains that "sub" is in the inner class, which is the ActionListener class, must be declared final. Please tell me what to do with it. I want to add an ActionListener to each MyButton Object in the array. Thanks ......

    OK, now I changed my code to this :
    for ( int i = 0; i <= 2; i++ ) {
      for ( int j = 0; j <= 2; j++ ) {
        grids[i][j] = new MyButton ();
        grids[i][j].setBorder(but);
        getContentPane().add(grids[i][j]);
        grids[i][j].addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            if ( grids[i][j].getState() == 0 ) {
               grids[i][j] = new MyButton( (Icon) new ImageIcon(imageFile));
              if ( imageFile.equals("cross.jpg") ) {
               grids[i][j].changeState(1);
              else {
              grids[i][j].changeState(2);
    [/cpde]
    Thanks for your advice !!!!!!
    Now the compiler says that i and j are local variables accessed from inner classes, needs to be declared final. How can I solve this then ???

  • A question about local inner classes

    Suppose an inner class created in a method:
    public void thisMethod(final int a){
                 class InnerClass {
                   //code
    }Why, in order to use the parameter a in the inner class, I have to pass it final?

    Aurelious wrote:
    JoachimSauer wrote:
    Because you can't refer to the argument of a method once the method call is completed (since the method argument lives on the stack).Why does that matter? If the parameter is of a primitive type, the object will get a copy of it anyway. If the parameter is not primitive, then the value on the stack will be a reference to the argument and not the argument-object itself. In either case, it should then be safe to modify the value after the method returns, as it will either be the primitive copy or a copy of a reference to the object which is itself not on the stack, so the field referenced by the object is still valid either way.
    Am I missing something?If your inner class is using a local variable in the calling method, the expectation is that it's the same variable. But it's not. If it were, then when the stack frame was popped, the variable would be out of scope, which is incompatible with the fact that the inner object can live on.
    On the other hand, if we copy it without making it final, then that's misleading. It looks like I have the same variable, but if I change it in the method, it doesn't change in the object, and vice versa.
    So we have to make a copy to prevent scope/lifetime problems, and we have to make it final so that the copy can be indistinguishable from it being the same variable.

  • Local inner class scope

    Hello all,
    I am working out of "Thinking in Java" and ran across something I simply don't get. A method is called and passed an argument. This method defines an inner class and returns reference to it. Later a method in the inner class is invoked, but it still has access to the argument passed to the method that created the inner class and completed.
    Here is the code (shortened from the book):
    interface Counter {
         int next();
    } // close interface Counter
    public class LocalInnerClass {
         private int count = 0;
         Counter getCounter( final String name ) {
              class LocalCounter implements Counter {
                   public int next() {
                        System.out.print( name );
                        return count++;
                   } // close next()
              } // close inner class
              return new LocalCounter();
         } // close getCounter()
         public static void main( String[] args ) {
              LocalInnerClass lic = new LocalInnerClass();
              Counter c1 = lic.getCounter( "Local inner " );
              for( int i = 0; i < 5; i++ ) {
                   System.out.println( c1.next() );
              } // close for
         } // close main()
    } // close classAnd here is what is produced from running this:
    Local inner 0
    Local inner 1
    Local inner 2
    Local inner 3
    Local inner 4The string "Local inner" is passed to the method getCouter as a final String. getCounter creates the class and exits. Later a method in getCounter uses that final String "next". This is where I am lost - getCounter is done and gone, so how the heck is name accessible to the inner class?!?!
    Just when I thought I was getting the hang of this ;)

    So trying to redeem myself...
    You can use "javap -c" to see what a compiler is really doing.
    So using javap (version 1.4.2_04) on the inner class gives the following....
    class LocalInnerClass$1LocalCounter extends java.lang.Object implements Counter{
    LocalInnerClass$1LocalCounter(LocalInnerClass,java.lang.String);
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   aload_0
       5:   aload_1
       6:   putfield        #2; //Field this$0:LLocalInnerClass;
       9:   aload_0
       10:  aload_2
       11:  putfield        #3; //Field val$name:Ljava/lang/String;
       14:  return
    public int next();
      Code:
       0:   getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
       3:   aload_0
       4:   getfield        #3; //Field val$name:Ljava/lang/String;
       7:   invokevirtual   #5; //Method java/io/PrintStream.print:(Ljava/lang/String;)V
       10:  aload_0
       11:  getfield        #2; //Field this$0:LLocalInnerClass;
       14:  invokestatic    #6; //Method LocalInnerClass.access$008:(LLocalInnerClass;)I
       17:  ireturn
    The second method in the above is the next() method.
    The next() method uses the "getfield" bytecode to retrieve a member variable of the class which is named "val$name".
    The first method in the above is a constructor which takes a string as the only parameter. That string is saved in the member variable of the class called "val$name".
    It is preserving a reference, so if a StringBuffer was used rather than a String then one could alter the value in the for loop of the original code and see the change.

  • Methods or inner classes?

    Is there much difference, performance wise between a class method and an inner class? I am writing a 3d application where performance is of the essence, I can either put my code in seperate moethds or inner classes. The code is more managable when I use inner classes but I was wondering whether this was slower.
    Thanks.

    blink I presume your inner classes would have methods, right? Anyway,
    1. Don't prematurely optimise.
    2. Don't prematurely optimise.
    3. Object creation is the only thing which would cause any extra cost. But it's extremely unlikely to be a bottleneck.

  • Sending sms/iMsg to someone with iPad and non-iPhone via Siri

    Hi there,
    We hit a glitch with sending text messages via Siri.
    I have an iPad and an Android phone.  Using iMessage between my iPad and her iPhone works fine.  She can also send a text to my phone with no trouble by making sure she selects the "SMS" thread in iMessage (which is a whole other annoyance...). 
    The problem is when she asks Siri to send me a text message, it defaults to sending an iMessage to my iPad, and therefore nothing goes to my phone.  That kind of ruins what would be a very frequently used feature.   Any ideas on how to get it to default to the phone number and not apple ID?
    Thanks!
    -Sean

    Hi Sean,
    First of all, check what the two phone numbers are called in her contacts (i.e. "home", "mobile", etc.) If your android phone is titled "mobile", ask Siri, "Text Sean, mobile..." and tell her your message. Siri seems to get confused sometimes when you text two numbers under the same contact. Hope this helps!

  • Non-final variable inside an inner class - my nemisis

    I have an issue with accessing variables from an inner method. This structure seems to allow access to the text objects but not to the button object. This comes from a bit of example code that just illustrates a simple form window with text fields and buttons that read them.
    At the start of the class I have text objects defined like this:
    public class SimpleGUI extends Composite {
    Text nameField;
    Text junkField;
    // Constructors come next, etc...
    Later within this class there is a method to create some GUI stuff, and then to create a button and when pressed access and print the text to the console
    protected void createGui(){
    junkField = new Text(entryGroup,SWT.SINGLE); //Ross
    junkField.setText("Howdy");
    Button OKbutton = new Button(buttons,SWT.NONE);
    OKbutton.setText("Ok");
    OKbutton.addSelectionListener(
    new MySelectionAdapter() {
    public void widgetSelected(SelectionEvent e) {
    System.out.println("Name: " + nameField.getText());
    System.out.println("Junk: " + junkField.getText());
    And that all works fine. So within the inner class, the object junkField can be accessed nicely.
    However if I try to do the same with the button (I want to change the label on the button after it's pressed) I get errors for trying to access a non-final object in an inner class.
    I tried to handle the button similar to the text, adding this after the text defs:
         Button myButton;
    and under the println's in the inner class I wanted:
    if OKbutton.getText.equals("OK") {  OKbutton.setText("NotOK")}
    That's when I get an issue with "cannot refer to a non-final variable inside an inside class defined in a different method"
    Now, if I move the button declaration into the createGui method, and declare it with "final Button myButton" it works.
    Why does the button need different treatment than the text?
    Is this a suitable method to make my button change it's label when pressed, or is this sloppy?

    Button is a local variable. The anonymous inner class object you create can continue to exist after the method ends, but the local variables will not. Therefore, as the error message says, you must make that local button variable final if you want to refer to it inside the anon inner class. If it's final, a copy of its value can be given to the inner class--there's no need to treat it as "variable."

  • Actionlistener in swing won't let me play with my variables!

    I am sort of new to java, having done some scripting before, but not much programming experiance. OOP was, until I learned java, something I didn't use that much. All this static and public stuff was hard at first, but I finally think I understand it all.
    I am still learning java, and for one of my projects, I am trying to make a small quiz game to learn swing. I am having problems. My button actionlistener complains about my variables, and I have tried many things, like wrapping them in a container and moving them, but I cannot make it compile. Any help would be appriciated. Thanks in advance!
    //The program is a quiz thingy.
    //the error is down in the GUI section, where I make the button respond to commands
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.net.*;//for later use, download files to read off net
    import java.io.*;
    import java.math.*;
    import java.util.Random;
    public class Main {
    public static void main(String args[]) { 
      File file = new File("problems.txt");
      int probcount=5;
      int answercount=0;
      boolean onproblem = true;
      String[] Problems={"","","","","","","","","","","",""};//I find if I don't init, I get nullpointer errors
      String[] Answers={"","","","","","","","","","","",""};//sorry for the oddness
      String[] thetext=new String[100];
      int i=0;
      int t=0;
      if ( !file.exists(  ) || !file.canRead(  ) ) {
                    System.out.println( "Can't read " + file );
                    return;
                    try {
                        FileReader fr = new FileReader ( file );
                        BufferedReader in = new BufferedReader( fr );
                        String line;
                        while ((line = in.readLine(  )) != null ){
                            thetext=line;
    i++;
    catch ( FileNotFoundException e ) {
    System.out.println( "File Disappeared" );
    catch ( IOException e ) {
    System.out.println( "Error During File Reading" );
    boolean writetoprob = true;
    for(int y=0;y<i;y++)
    System.out.println(thetext[y]);
    for(int y=0;y<i;y++){
    if(thetext[y].equals("-")){
    if(writetoprob==true)
    writetoprob=false;
    else{
    writetoprob=true;
    t++;
    else{
    if(writetoprob==true)
    Problems[t]=Problems[t].concat("\n").concat(thetext[y]);
    else
    Answers[t]=Answers[t].concat("\n").concat(thetext[y]);
    System.out.println(Problems[0]);
    System.out.println(Problems[1]);
    //TODO:Randomize problems and display them, then answers when button clicked
    boolean answerbutton=true;
    int probindex=0;
    Random rnums = new Random();
    probindex=rnums.nextInt()%(t+1);
    if(probindex<0)
    probindex=-probindex;
    System.out.println(probindex);
    System.out.println(Problems[probindex]);
    JButton action = new JButton("Click for Answer!");
    JTextArea tp = new JTextArea(Problems[probindex]);
    JFrame jf = new JFrame();
    boolean onanswer = false;
    action.addActionListener( new ActionListener( ) {
    public void actionPerformed(ActionEvent theaction) {
    System.out.println(answerbutton);
    if(answerbutton==false){
    answerbutton=true;
    probindex=rnums.nextInt()%(t+1);
    if(probindex<0)
    probindex=-probindex;
    tp.setText(Problems[probindex]);
    else{
    answerbutton=false;
    tp.setText(Answers[probindex]);
    Container content = jf.getContentPane( );
    content.setLayout(new FlowLayout( ));
    content.add(tp);
    content.add(action);
    jf.pack();
    jf.setVisible(true);

    init:
    deps-jar:
    Compiling 1 source file to C:\Documents and Settings\Patrick\FirstCup\build\classes
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:91: local variable answerbutton is accessed from within inner class; needs to be declared final
    System.out.println(answerbutton);
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:92: local variable answerbutton is accessed from within inner class; needs to be declared final
    if(answerbutton==false){
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:93: local variable answerbutton is accessed from within inner class; needs to be declared final
    answerbutton=true;
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:94: local variable probindex is accessed from within inner class; needs to be declared final
    probindex=rnums.nextInt()%(t+1);
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:94: local variable rnums is accessed from within inner class; needs to be declared final
    probindex=rnums.nextInt()%(t+1);
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:94: local variable t is accessed from within inner class; needs to be declared final
    probindex=rnums.nextInt()%(t+1);
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:95: local variable probindex is accessed from within inner class; needs to be declared final
    if(probindex<0)
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:96: local variable probindex is accessed from within inner class; needs to be declared final
    probindex=-probindex;
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:96: local variable probindex is accessed from within inner class; needs to be declared final
    probindex=-probindex;
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:97: local variable Problems is accessed from within inner class; needs to be declared final
    tp.setText(Problems[probindex]);
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:97: local variable probindex is accessed from within inner class; needs to be declared final
    tp.setText(Problems[probindex]);
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:97: local variable tp is accessed from within inner class; needs to be declared final
    tp.setText(Problems[probindex]);
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:100: local variable answerbutton is accessed from within inner class; needs to be declared final
    answerbutton=false;
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:101: local variable Answers is accessed from within inner class; needs to be declared final
    tp.setText(Answers[probindex]);
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:101: local variable probindex is accessed from within inner class; needs to be declared final
    tp.setText(Answers[probindex]);
    C:\Documents and Settings\Patrick\FirstCup\src\firstcup\Main.java:101: local variable tp is accessed from within inner class; needs to be declared final
    tp.setText(Answers[probindex]);
    16 errors
    BUILD FAILED (total time: 3 seconds)

Maybe you are looking for

  • How do I creat an app say games that I can store all my games under?

    HOw can I creat a master app that I can store other apps in. For example creating a master app such as games that all games would be stored under?

  • How Far Back Oracle Keep AWR Reports

    Hello, A quick question: Does anyone know how far back Oracle retain AWR reports in the database? Is this something that we can customize? If it is, can someone offer some insights? Thanks!

  • Which tool i should choose

    I am a Jackeroo in javaprogramming . I wanna establish a webpage with JSP. Can anyone tell me which tool i should use.and which languange i should take.J2EE or J2SE or anythingelse. Thanx for all the reply

  • HT5621 I am unable to enter my Apple ID on my phone

    I changed my apple ID a few months ago and apparently it didn't change on my iCloud and now the phone won't allow me to change it so I can sign in. How can I change that?

  • Customer Exit  EXIT_SAPLRRS0_001

    Hi Experts, can some make pointer regarding the authorisation in the exit EXIT_SAPLRRS0_001 1)Value Authorization 2)Hierarchy Authorization. which one will be better, and in detail about both the Authorization. Thankyou.