|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
[Java] inner-class anonima e variabili final
Premessa: una inner-class anonima all'interno di un metodo non può accedere alle variabili locali del metodo .... a meno che la variabile sia marcata final.
Su questo non ci piove. Volevo però capire bene cosa succede "dietro le quinte" per via del final. Ho scritto un breve programma di esempio, del tutto inutile .... Codice:
public class Prova { public static void main (String[] args) { Prova p = new Prova (); Object o = p.create ("Hello"); System.out.println (o); } public Object create (final String str) { return new Object () { private String text = str; public String toString () { return "Anonymous, text=" + text; } }; } } Codice:
import java.io.PrintStream; public class Prova { public Prova() { } public static void main(String args[]) { Prova prova = new Prova(); Object obj = prova.create("Hello"); System.out.println(obj); } public Object create(final String str) { return new Object() { public String toString() { return (new StringBuilder()).append("Anonymous, text=").append(text).toString(); } private String text; final String val$str; final Prova this$0; { this$0 = Prova.this; str = s; super(); text = str; } } ; } } Codice:
final class Prova$1 { public String toString() { return (new StringBuilder()).append("Anonymous, text=").append(text).toString(); } private String text; final String val$str; final Prova this$0; Prova$1() { this$0 = final_prova; val$str = String.this; super(); text = val$str; } }
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
![]() |
![]() |
![]() |
#2 |
Bannato
Iscritto dal: Feb 2003
Città: Anche Chuck Norris usa Debian e Gnome
Messaggi: 1270
|
Ma ora se ricompili questi due file usciti fuori da jad cosa succede?
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Jan 2001
Città: Milano
Messaggi: 5707
|
non è un buon approccio quello che stai seguendo, jad non sempre riesce a ricavare il sorgente dal bytecode (e questo è il caso, il codice che hai postato non compila neanche).
in realtà la inner viene tradotta in una classe con un costruttore che prende in ingresso un'istanza della outer e la stringa a cui accedi (e che vengono salvate in due attributi final). sto pensando al perchè anche la stringa debba essere marcata final, ma non capisco ![]() |
![]() |
![]() |
![]() |
#4 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
![]() Se il tool jad, come dici, non è adatto, magari posso poi provare con un altro decompilatore. Molto probabilmente quelle cose che ho evidenziato (es. String.this) sono errori del jad. In effetti così sembra logico, dato che il costruttore viene generato appositamente dal compilatore.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Jan 2001
Città: Milano
Messaggi: 5707
|
Quote:
javap -c NOmeClasse ti permette di disassemblare il codice per vedere effettivamente come viene trasformato in bytecode il tuo sorgente. i commenti con i parametri e le variabili ti permettono di seguire abbastanza facilmente il codice. |
|
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Codice:
Compiled from "Prova.java" final class Prova$1 extends java.lang.Object{ Prova$1(Prova, java.lang.String); Code: 0: aload_0 1: aload_1 2: putfield #1; //Field this$0:LProva; 5: aload_0 6: aload_2 7: putfield #2; //Field val$str:Ljava/lang/String; ... .... Interessante ... grazie per il suggerimento. ![]()
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 22:21.