Il formato bytecode JVM consente la dichiarazione di più metodi con lo stesso nome e gli stessi tipi di parametri purché il tipo restituito sia diverso, sebbene Java linguaggio non lo consenta.. Ciò significa che a) altre lingue JVM possono farne uso eb) può essere utilizzato per speciali caratteristiche del linguaggio "compiler-magic".
Più comunemente, il compilatore emette più metodi con lo stesso nome e gli stessi tipi di parametri quando si tratta di generici. La ricerca del metodo JVM si basa sull'intera firma per corrispondere, non solo sui tipi di parametri. Pertanto, il compilatore deve emettere i cosiddetti metodi bridge
che sovrascrivono o ombreggiano altri metodi in base alla firma. Considerate questo esempio:
interface Foo<T>
{
T foo(); // desc:()Ljava/lang/Object;
void bar(T value); // desc: (Ljava/lang/Object;)V
Object baz(); // desc:()Ljava/lang/Object;
}
class StringFoo implements Foo<String>
{
@Override
public String foo() { ... } // desc:()Ljava/lang/String; // !
@Override
public void bar(String value) { ... } // desc: (Ljava/lang/String;)V // !
@Override
public String baz() { ... } // desc:()Ljava/lang/String; // !
}
La classe StringFoo
bisogno di tre metodi bridge aggiuntivi per sovrascrivere effettivamente i metodi di interfaccia in termini di avere lo stesso desc
:
class StringFoo implements Foo<String>
{
public String foo() { ... }
public /* synthetic bridge */ Object foo() // desc:()Ljava/lang/Object;
{
return /* String */ foo(); // statically linked to String foo()
}
public void bar(String value) { ... }
public /* synthetic bridge */ void bar(Object value) // desc: (Ljava/lang/Object;)
{
return bar((String) value);
}
public String baz() { ... }
public /* synthetic bridge */ Object baz() // desc:()Ljava/lang/Object;
{
return /* String */ baz(); // statically linked to String baz()
}
}
Le pseudo-modificatori synthetic bridge
sono due accessi JVM contrassegni utilizzati solo dal compilatore per contrassegnare i metodi generati automaticamente nel bytecode
La metrica Class#getDeclaredMethods
od restituisce tutti i metodi dichiarati - inclusi i metodi di bridge sintetici. Pertanto, #getDeclaredMethod(String)
deve sceglierne uno che è l'implementazione effettiva.
probabilmente un metodo privato da una classe genitore che corrisponde a un metodo figlio? – flakes
@flkes No, poiché 'getDeclaredMethods' trova solo metodi dichiarati sulla classe. Dovresti sempre trovare il metodo dichiarato sul bambino. – Radiodef