I have the following static factory method that creates a list view out of an int array:
public static List<Integer> newInstance(final int[] numbers) {
return new AbstractList<Integer>() {
@Override
public Integer get(int index) {
return numbers[index];
}
@Override
public int size() {
return numbers.length;
}
};
}
public static void main(String[] args) {
int[] sequence = {10, 20, 30};
List<Integer> list = ListFactory.newInstance(sequence);
System.out.println("List is "+list);
}
In "Effective Java", Joshua Bloch mentioned this
as an Adapter that allows an int array to be viewed as a list of Integer instances.
However, I remember that Adapter uses composition and the instance of the anonymous list implementation should use the int[] as a member field.
Where exactly is the int[] input parameter stored if it's not a member field of the anonymous list implementation?
I would appreciate if anyone could provide some insights or some links to look for more information.
Anonymous classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.
Anonymous inner classes can be defined not just within a method, but even within an argument to a method. Anonymous inner classes cannot have explicit constructors declared because they have no name to give the constructor.
It is an inner class without a name and for which only a single object is created. An anonymous inner class can be useful when making an instance of an object with certain “extras” such as overriding methods of a class or interface, without having to actually subclass a class.
Object = new Example() { public void display() { System. out. println("Anonymous class overrides the method display()."); } }; Here, an object of the anonymous class is created dynamically when we need to override the display() method.
You can use javac -d . -XD-printflat ListFactory.java
to see how the compiler understands the inner class. Actually, there are two Java classes in your example. The ListFactory
(note how numbers
are passed to the constructor of ListFactory$1
):
public class ListFactory {
public ListFactory() {
super();
}
public static List newInstance(final int[] numbers) {
return new ListFactory$1(numbers);
}
}
and the representation of the anonymous implementation of AbstractList
:
class ListFactory$1 extends AbstractList {
/*synthetic*/ final int[] val$numbers;
ListFactory$1(/*synthetic*/ final int[] val$numbers) {
this.val$numbers = val$numbers;
super();
}
@Override()
public Integer get(int index) {
return Integer.valueOf(val$numbers[index]);
}
@Override()
public int size() {
return val$numbers.length;
}
@Override()
/*synthetic*/ public Object get(/*synthetic*/ int index) {
return this.get(index);
}
}
The methods and fields marked as synthetic are generated by the compiler and not accessible to you as a programmer, but are used during runtime to access the int array. And indeed there is a val$numbers
field that holds a final reference to the int array.
By the way you can also notice boxing from int
to Integer
in Integer get(int index)
and that to comply with the raw (non-generic) List
interface an extra Object get(int index)
method is generated that delegates to the type-safe Integer get(int index)
implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With