2

早些时候,当内部匿名类没有看到“外部”类的字段时,我遇到了问题。我需要制作一个最终变量以使其对内部类可见。现在我有一个相反的情况。在“外部”类“ClientListener”中,我使用内部类“Thread”和“Thread”类,我有“run”方法,并且确实从“outer”类中看到了“earPort”!为什么?

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();      
    }

}
4

2 回答 2

12

匿名内部类可以访问静态和实例变量。如果您还想访问局部变量,请将它们声明为 final。这就是它的工作原理:)

于 2010-03-23T11:06:07.850 回答
1

您的匿名内部类可以访问包含对象的属性。所有未声明的内部类static都有一个隐式访问器。

如果你想防止这种情况发生,你可以声明一个静态内部类并实例化它:

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("");
            }
        }
    };
}
于 2010-03-23T11:16:24.723 回答