Justin tiene el caso general abajo; Quería mencionar dos casos especiales demostradas por esta 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;
}
}
Esta impresora:
SomeRefiedGeneric.compare() called by: SomeReifiedGeneric.compare(WhoCalledMe.java:1)
somePrivateMethod() called by: WhoCalledMe.access$0(WhoCalledMe.java:14)
pesar de que el primero se llama "directamente" de main()
y el segundo de SomeInnerClass.someInnerMethod()
. Estos son dos casos donde hay una llamada transparente hecha entre los dos métodos.
- En el primer caso, esto se debe a que estamos llamando la bridge method a un método genérico, añadido por el compilador para asegurar SomeReifiedGeneric se puede utilizar como un tipo de prima.
- En el segundo caso, es porque estamos llamando a un miembro privado de WhoCalledMe de una clase interna. Para lograr esto, el compilador agrega un método sintético como intermediario para anular los problemas de visibilidad.
Me sorprenden repetidamente los hacks raros que algunas personas "quisieran escribir". Sin ofender. – delnan
@del Esto no es realmente un truco. Básicamente es una forma de registro que puede ser realmente útil. – jjnguy
geeking out .. :-) – DuduAlul