views:

126

answers:

2

Earlier I had a problem when an inner anonymous class did not see a field of the "outer" class. I needed to make a final variable to make it visible to the inner class. Now I have an opposite situation. In the "outer" class "ClientListener" I use an inner class "Thread" and the "Thread" class I have the "run" method and does see the "earPort" from the "outer" class! Why?

import java.io.IOException;
import java.net.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class ClientsListener {

    private int earPort;

    // Constructor.
    public ClientsListener(int earPort) {
        this.earPort = earPort;
    }

    public void starListening() {

        Thread inputStreamsGenerator = new Thread() {
            public void run() {
                System.out.println(earPort);
                try {
                    System.out.println(earPort);
                    ServerSocket listeningSocket = new ServerSocket(earPort);
                    Socket serverSideSocket = listeningSocket.accept();
                    BufferedReader in = new BufferedReader(new InputStreamReader(serverSideSocket.getInputStream()));
                } catch (IOException e) {
                    System.out.println("");
                }
            }
        };
        inputStreamsGenerator.start();      
    }

}
+11  A: 

Anonymous inner classes have access to static and instance variables. If you want to have also access to local variables, declare them as final. This is how it works:)

Petar Minchev
+1  A: 

Your anonymous inner class has access to the attributes of the containing object. All inner classes that are not declared static have an implicit accessor.

If you want to prevent this from happening, you can declare a static inner class and instantiate that:

public class ClientsListener {

    private int earPort;

    // Constructor.
    public ClientsListener(int earPort) {
        this.earPort = earPort;
    }

    public void starListening() {

        Thread inputStreamsGenerator = new InputStreamsGenerator();
        inputStreamsGenerator.start();      
    }

    private static class InputStreamsGenerator extends Thread() {
        public void run() {
            // no access to earport in next line (can make it a constructor argument)
            System.out.println(earPort);
            try {
                System.out.println(earPort);
                ServerSocket listeningSocket = new ServerSocket(earPort);
                Socket serverSideSocket = listeningSocket.accept();
                BufferedReader in = new BufferedReader(new InputStreamReader(serverSideSocket.getInputStream()));
            } catch (IOException e) {
                System.out.println("");
            }
        }
    };
}
rsp