Why variable n isn't visible in second listener in Java?

I don't know why variable n isn't visible in second listener. All is in the question. Below I adding a code. This is only a part of all source code.

ActionListener lis5 = new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        String a = t1.getText();
        int n = Integer.parseInt(a);
    } 
};
b1.addActionListener(lis5);

ActionListener lis6 = new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        int [] tab = new int[n];
        for (int i=0;i<n;i++) {
            tab[i] = in.nextInt();
        }
    } 
};
b2.addActionListener(lis6); 

Answers


Because n is in the scope of an anonymous interface.

  • Accessing Local Variables of the Enclosing Scope, and Declaring and Accessing Members of the Anonymous Class
  • Like local classes, anonymous classes can capture variables; they have the same access to local variables of the enclosing scope:

    An anonymous class has access to the members of its enclosing class.

    An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final.

    Like a nested class, a declaration of a type (such as a variable) in an anonymous class shadows any other declarations in the enclosing scope that have the same name. See Shadowing for more information.

    Anonymous classes also have the same restrictions as local classes with respect to their members:

    You cannot declare static initializers or member interfaces in an anonymous class.

    An anonymous class can have static members provided that they are constant variables.


    n is declared in the scope of the first actionPerformed. It will "disappear" as soon as the method ends.

    Declare it outside of the methods

    int n = 0;
    
    ActionListener lis5 = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            String a = t1.getText();
            n = Integer.parseInt(a)
        } 
    };
    b1.addActionListener(lis5); 
    
    int[] tab;
    
    ActionListener lis6 = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            tab = new int[n];
            for(int i = 0 ; i < n ; i++) {
                tab[i] = in.nextInt();
            }
        } 
    };
    b2.addActionListener(lis6);
    

    Same goes for the deceleration of tab array.


    If you need to be able to update the variable in one action listener, and then use it in another action listener, you need a reference to a mutable value type to share between the two.

    You can simply use int[1], but I prefer to use AtomicInteger, since it is more clear that there is exactly one integer value being shared then:

    final AtomicInteger n = new AtomicInteger();
    ActionListener lis5 = new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            String a = t1.getText();
            n.set(Integer.parseInt(a));
        } 
    };
    b1.addActionListener(lis5); 
    
    ActionListener lis6 = new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            int nn = n.get();
            int [] tab = new int[nn];
            for(int i=0;i<nn;i++){
                tab[i] = in.nextInt();
            }
        } 
    };
    b2.addActionListener(lis6); 
    

    Need Your Help

    Create Edmx from C# Code - Not from database

    c# frameworks entity

    Is it possible to generate an Edmx file by creating the collections (schema, conceptual, mappings) and mappings in code and building it up in C#?