Взгляните на следующий код:
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 отслеживает ссылку на объект, переданный в качестве параметра тому методу?
Любая справка значительно ценилась бы!
[Извините за мой плохой английский язык! Если Вы понимаете мой вопрос, отредактируйте это сообщение и удалите грамматические ошибки.Спасибо!]
По существу код переписывается компилятором, так как (обратите внимание, что я не пытался его скомпилировать..., могут быть ошибки):
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);
}
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 позволяет такое странное как раз для того, чтобы облегчить программистам задачу. Оба кода семантически одинаковы и сводятся к идентичному байткоду.
.