On 05/12/11 10:20, Rémi Forax wrote:
While removing generics warnings in java.util,
I've seen that some anonymous classes are coded in a way that
make javac to generate too much fields.
This code:
final List<String> list = Arrays.asList(args);
Iterator<String> iterator = new Iterator<String>() {
private Iterator<String> it = list.iterator();
...
}
};
generates an anonymous class with two fields:
final class Foo$1 implements java.util.Iterator<java.lang.String> {
java.util.Iterator<java.lang.String> it;
final java.util.List val$list;
FinalCaptureTooBig$1(java.util.List);
...
while this code:
List<String> list = Arrays.asList(args);
final Iterator<String> it = list.iterator();
Iterator<String> iterator = new Iterator<String>() {
...
generates an anonymous class with only one field:
final class FinalCaptureTooBig$1 implements
java.util.Iterator<java.lang.String> {
final java.util.Iterator val$it;
FinalCaptureTooBig$1(java.util.Iterator);
...
If javac was smart, it should generate only one field because the
variable 'list' is only
use in the initializer of a field, so 'list' has to be passed as
parameter of the constructor
but don't need to be stored as a field.
Note that this change in javac may break the serialization compatibility,
so may be it's not a good idea to change javac. Or we can say that we
don't care
because there is an item in Effective Java that says that you should
not use
an anonynous class.
Should we change the code of java.util or javac ?
My 0.02$ is that it is potentially a risky change (as you point out) to
do in the compiler, and not such a straightforward one as well (javac
currently does not distinguish as to whether a variable is accessed from
a variable initializer w.r.t. form inside a method body). Of course, it
could be done - but I think it'd be wiser to invest time on making
lambda better so that people will be less and less forced to use inner
classes ;-)
Maurizio
cheers,
Rémi