Justin ha risolto il caso generale; Ho voluto citare due casi particolari dimostrate da questo snippit:
import java.util.Comparator;
public class WhoCalledMe {
public static void main(String[] args) {
((Comparator)(new SomeReifiedGeneric())).compare(null, null);
new WhoCalledMe().new SomeInnerClass().someInnerMethod();
}
public static StackTraceElement getCaller() {
//since it's a library function we use 3 instead of 2 to ignore ourself
return Thread.currentThread().getStackTrace()[3];
}
private void somePrivateMethod() {
System.out.println("somePrivateMethod() called by: " + WhoCalledMe.getCaller());
}
private class SomeInnerClass {
public void someInnerMethod() {
somePrivateMethod();
}
}
}
class SomeReifiedGeneric implements Comparator<SomeReifiedGeneric> {
public int compare(SomeReifiedGeneric o1, SomeReifiedGeneric o2) {
System.out.println("SomeRefiedGeneric.compare() called by: " + WhoCalledMe.getCaller());
return 0;
}
}
Questo stampa:
SomeRefiedGeneric.compare() called by: SomeReifiedGeneric.compare(WhoCalledMe.java:1)
somePrivateMethod() called by: WhoCalledMe.access$0(WhoCalledMe.java:14)
Anche se il primo si chiama "direttamente" dal main()
e il secondo da SomeInnerClass.someInnerMethod()
. Questi sono due casi in cui è presente una chiamata trasparente tra i due metodi.
- Nel primo caso, questo è perché che chiamiamo bridge method ad un metodo generico, aggiunto dal compilatore per garantire SomeReifiedGeneric può essere utilizzato come un tipo grezzo.
- Nel secondo caso, è perché stiamo chiamando un membro privato di WhoCalledMe da una classe interna. Per fare ciò, il compilatore aggiunge un metodo sintetico come intermediario per ignorare i problemi di visibilità.
fonte
2010-08-12 15:47:41
Sono ripetutamente sbalordito da quello strano hacks che alcune persone "vorrebbero scrivere". Senza offesa significava. – delnan
@del Questo non è davvero un hack. È fondamentalmente una forma di registrazione che può essere davvero utile. – jjnguy
geeking out .. :-) – DuduAlul