When I find something interesting and new, I post it here - that's mostly programming, of course, not everything.

Thursday, December 25, 2008

Inner Class in Java: Unexpected Volatility

You probably know that if you use a value in an inner class, the evil Java compiler wants you to write "final"; people do all kinds of trick to bypass it - store date in arrays, for instance.

But relax, you do not have to write "final" if it is a member field. Look at this code:

package experimental;

import java.util.AbstractSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class VolatileConstant {

public static void main(String[] args) {
Iterable<Set<String>> iss = new Iterable<Set<String>>() {

public Iterator<Set<String>> iterator() {
return new Iterator<Set<String>>() {
int i = 0;
public boolean hasNext() {
return i < 3;
}

public Set<String> next() {
i++;

return new AbstractSet<String>() {
public Iterator<String> iterator() {
return new Iterator<String>() {
int j = 0;
public boolean hasNext() {
return j < i;
}

public String next() {
j++;
return "" + i + "." + j;
}

public void remove() {
throw new UnsupportedOperationException();
}
};
}

public int size() {
return i;
}
};
}

public void remove() {
throw new UnsupportedOperationException();
}
};
}
};

Set<Set<String>> sss = new HashSet<Set<String>>();

for (Set<String> ss : iss) {
sss.add(ss);
System.out.println(ss);
}
System.out.println(sss);
}
}


You know what it prints? It's in the next line, in white color so that you have a choice not to see it.

[1.1]
[2.1, 2.2]
[3.1, 3.2, 3.3]
[[3.1, 3.2, 3.3], [3.1, 3.2, 3.3], [3.1, 3.2, 3.3]]


I am sure you can explain it, after a while, but is not it really amusing?

1 comment:

Stan Klimoff said...

AFAIR, in .NET 2.0 this is the expected behavior even for the local variables. Compiler simply promotes the local variable to a member one if it is used in the closure.

Followers

Subscribe To My Podcast

whos.amung.us