问题
Please have a look at following code :
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);
}
In the above code, the instance of an anonymous inner class declared in the method modifiedList() is able to access the parameter passed to that method. AFAIK Java creates a separate bytecode file for inner classes.
Can anyone explain how these local variable bindings are handled by Java at the bytecode level? I mean, how exactly does Java keep track of the reference to the object passed as a parameter to that method?
Any help would be greatly appreciated!
[Sorry for my poor English! If you understand my question, please edit this post and remove the grammatical errors. Thanks!]
回答1:
Essentially the code is rewritten by the complier as (note I didn't try to compile it..., might have errors):
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);
}
}
and
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);
}
回答2:
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 allows such a strange thing just in order to make things easier for programmers. Both the codes are semantically same and boil down to the identical bytecode.
来源:https://stackoverflow.com/questions/1950807/anonymous-inner-classes-inside-methods