6

次のコードをご覧ください。

import java.util.ArrayList;
import java.util.List;

class Main{
     public static <T> List<T> modifiedList(final List<T> list){
         return new ArrayList<T>(){
            @Override
             public boolean add(T element){
                 super.add(element);
                 return list.add(element);
             }
         };
    }

     public static void main(String[] args) {
         List<String> originalList=new ArrayList<String>();
         List<String> duplicateList=modifiedList(originalList);
         originalList.add("1");
         originalList.add("2");
         originalList.add("3");
         System.out.println(originalList+" "+duplicateList);
         duplicateList.add("4");
         duplicateList.add("5");
         duplicateList.add("6");
         System.out.println(originalList+" "+duplicateList);
     }

上記のコードでは、メソッドmodifiedList()で宣言された匿名内部クラスのインスタンスは、そのメソッドに渡されたパラメーターにアクセスできます。AFAIK Javaは、内部クラス用に個別のバイトコードファイルを作成します。

これらのローカル変数バインディングがJavaによってバイトコードレベルでどのように処理されるかを誰かが説明できますか?つまり、Javaは、そのメソッドにパラメーターとして渡されたオブジェクトへの参照をどの程度正確に追跡しますか?

どんな助けでも大歓迎です!

[英語が下手でごめんなさい!私の質問を理解したら、この投稿を編集して文法上の誤りを取り除いてください。ありがとう!]

4

2 に答える 2

9

基本的に、コードはコンパイラによって次のように書き直されます(コンパイルしようとしなかったことに注意してください...、エラーが発生する可能性があります)。

class Main$1<T>
    extends ArrayList<T>
{
    private final List<T> list;

    Main$1(final List<T> a)
    {
        list = a;
    }

    @Override
    public boolean add(T element)
    {
        super.add(element);
        return list.add(element);
    }
}

class Main{
     public static <T> List<T> modifiedList(final List<T> list)
     {
         return new Main$1<T>(list);
     }

     public static void main(String[] args) 
     {
         List<String> originalList=new ArrayList<String>();
         List<String> duplicateList=modifiedList(originalList);
         originalList.add("1");
         originalList.add("2");
         originalList.add("3");
         System.out.println(originalList+" "+duplicateList);
         duplicateList.add("4");
         duplicateList.add("5");
         duplicateList.add("6");
         System.out.println(originalList+" "+duplicateList);
     }
于 2009-12-23T05:15:24.293 に答える
5
import java.util.ArrayList;
import java.util.List;

class Main{
    public static <T> List<T> modifiedList(final List<T> list){
         return new ArrayList<T>(){

             private List<T> originalList=list;

             @Override
             public boolean add(T element){
                 super.add(element);
                 return originalList.add(element);
             }
         };
     }

     public static void main(String[] args) {
         List<String> originalList=new ArrayList<String>();
         List<String> duplicateList=modifiedList(originalList);
         originalList.add("1");
         originalList.add("2");
         originalList.add("3");
         System.out.println(originalList+" "+duplicateList);
         duplicateList.add("4");
         duplicateList.add("5");
         duplicateList.add("6");
         System.out.println(originalList+" "+duplicateList);       
     }
 }

Java では、プログラマーにとって物事を簡単にするために、このような奇妙なことが許されています。両方のコードは意味的に同じであり、同じバイトコードに要約されます。

于 2009-12-23T21:02:43.593 に答える