to imho neni ani ted zapotrebi:
interface Iface
{
public int exec(int x);
}
public class Test
{
int x = 10;
public void run()
{
int y = 20;
Iface ii = new Iface() {
public int exec(int x)
{
return x+1;
}
};
System.out.println(ii.exec(1));
System.out.println(ii.exec(2));
}
public static void main(String[] args)
{
new Test().run();
}
}
tj. normalne se pristupuje jak k promennym tak i k atributum.
Tradiční řešení přístupu k lokálním proměnným je zabalit je do pole o velikosti jedna.
final int[] y = new int[1];
y[0] = 0;
new Runnable() {
public void run() {
y[0]++;
}
}.run();
assert y[0] == 1;
Neexistuje jediný technický důvod, proč by překladač Javy nemohl automaticky balit proměnné ze zásobníku. Lidé by pak klidně mohli psát:
int y = 0;
new Runnable() {
public void run() {
y++;
}
}.run();
assert y == 1;
což by bylo přirozené a čitelnější. Překladač by to pak upravil do výše popsané formy pole s jedním prvkem. Všichni vědí, že by to šlo a čas od času někdo i navrhne, že by se to mohlo udělat. Bohužel tento nápad má v Santa Kláře vlivné odpůrce, kteří jej vždy smetou ze stolu.
Mám pocit, že jeden z návrhů na lambdy obsahoval i možnost plnohodnotného přístupu na lokální proměnné (snad se musely oanotovat pomocí @Shared), ale nevsadil bych si na to, že projde.
Myslím, že důvod je ten, že při překladu té anonymní třídy se z ní udělá obyčejná vnitřní třída a hodnota proměnné y se do ní promítne jako konstanta (atribut s modifikátorem final). Nic jiného než konstanta to ani být nemůže, protože proměnná y vnější třídy je mimo dosah (scope) – kód definovaný ve vnitřní třídě by za běhu neměl jak zjistit její hodnotu. Z toho pramení požadavek na neměnnost proměnné y.
K atributům vnější třídy má AnonClass přístup, takže tam požadavek na neměnnost hodnoty není.
Tak trochu se musim opravit, nemoznost pouziti
non-final varible prameni z toho ze local (non-final)
variable neprezijou navrat z funkce.
K y neni pristup ve vnitrni tride protoze y "zije"
jenom na stacku funkce "run" takze po navratu z funkce
"run" y neexistuje.
S tim scopem bych byl opatrnejsi, protoze final variable
neni jenom "compile-time" konstanta jako treba
final String test="test".
Muze to byt i final String test=new String("test")
coz uz je resolvovany v runtime a presto stale pouzitelny
ve vnitrni tride.
Když jsem psal o konstantě, měl jsem na mysli field (atribut) s modifikátorem final, bez ohledu na to, zda je jeho hodnota vyhodnocená při kompilaci nebo až za běhu. (Tuším, že u anonymních vnořených tříd je vždy předávaná prostřednictvím konstruktoru.)
Souhlasím, že vaše vysvětlení, že ne- final proměnná „nepřežije“ návrat z funkce, protože „žije“ jen na zásobníku (stacku), je přesnější než vysvětlení se scopem.