Анонимные внутренние классы в методах

Взгляните на следующий код:

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 (), может получить доступ к параметру, переданному тому методу. Java AFAIK создает отдельный файл байт-кода для внутренних классов.

Кто-либо может объяснить, как эта привязка локальной переменной обрабатывается Java на уровне байт-кода? Я имею в виду, как точно Java отслеживает ссылку на объект, переданный в качестве параметра тому методу?

Любая справка значительно ценилась бы!

[Извините за мой плохой английский язык! Если Вы понимаете мой вопрос, отредактируйте это сообщение и удалите грамматические ошибки.Спасибо!]

6
задан Amber 23 December 2009 в 05:14
поделиться

2 ответа

По существу код переписывается компилятором, так как (обратите внимание, что я не пытался его скомпилировать..., могут быть ошибки):

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);
     }
9
ответ дан 8 December 2019 в 17:22
поделиться
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 позволяет такое странное как раз для того, чтобы облегчить программистам задачу. Оба кода семантически одинаковы и сводятся к идентичному байткоду.

.
5
ответ дан 8 December 2019 в 17:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: