2

以前、内部の匿名クラスが「外部」クラスのフィールドを認識していなかったときに問題が発生しました。内部クラスに表示されるように、final変数を作成する必要がありました。今、私は反対の状況にあります。「outer」クラス「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 に答える