On 12/05/2011 11:37 AM, Maurizio Cimadamore wrote:
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 ;-)
But defining an Iterator as a lambda is only possible if we support
generators and
we currently don't :(
Maurizio
Rémi