Java >> Java tutorial >  >> Tag >> return

Refleksion - Method::getGenericReturnType ingen generisk - synlighed

Lad os tage det langsomt her. Først og fremmest, her er grunden til, at en brometode genereres til at begynde med. Selvom du dropper generika, vil der stadig være en bridge-metode. Det vil sige denne kode:

static class A {
    public String foo() { return null; }
}

public static class B extends A {}

vil stadig generere en foo metode med ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC . Du kan læse fejlbeskrivelsen og forstå, hvorfor det er nødvendigt.

På den anden side hvis du laver A public , en sådan metode vil ikke genereres, burde årsagen være indlysende, i betragtning af den tidligere fejlforklaring (håber jeg). Så tanken er, at hvis du har en ikke-offentlig klasse, javac vil generere en brometode til scenariet ovenfor.

Nu, hvis du tilføjer generiske stoffer til den blanding af syntetiske metoder, begynder tingene at kaste lidt lys. For eksempel har du dette:

interface WithGeneric<T> {
    public WithGeneric<T> self(T s);
}

public class Impl implements WithGeneric<String> {

    @Override
    public WithGeneric<String> self(String s) {
        return null;
    }
}

Der vil også blive genereret en brometode i Impl.class , men dens erklæring vil være sletning af grænsefladen. Med andre ord vil der være to metoder i Impl.class :

public WithGeneric<String> self(String) {...}

public WithGeneric self(Object) {...}

Hvis du limer disse to ting:

  • i tilfælde af ikke-offentlige klasser vil en bridge-metode blive oprettet (så at refleksion ville fungere)

  • i tilfælde af generiske stoffer en slettet bridge-metoden vil blive oprettet (så at slettede opkald ville fungere)

ting vil give (på en eller anden måde) mening.


Når du erklærer A offentlig, B.class.getMethods()[0] henviser ikke til B; Det refererer til A.foo() , hvor metoden er erklæret, og typen er opnået på grund af eksistensen af ​​signature .

Erklærer A ikke-offentlige styrker B.class.getMethods()[0] reference B.foo() .

Da der ikke er nogen erklæring om den nedarvede metode, kan typen ikke hentes fra opkaldet til getGenericReturnType på grund af typesletning, der anvendes på generiske lægemidler.

I kompileringstid:

List<String> foo() bliver List foo() .

Og det er alle oplysningerne B kunne give dig angående metodens returtype, da signaturen i B.foo() blev lige fjernet.

Begge A og B hold den samme returtype for foo() :java.util.List (uden parametertype )

Dette er A.foo() 's erklærede returtype. Det samme som B.foo() :

Forskellen er, at A har en gyldig signatur, så den fuldender resultatet fra opkaldet til getGenericReturnType() ved at tilføje parametertyperne.

I tilfælde af B , vil den kun vise, hvad den ved:kun returtypen.

Jeg fik stærk hovedpine, da jeg prøvede at løse synlighedspuslespillet. For en fuldstændig forklaring på hvorfor dette sker, se op på Eugenes svar. Seriøst, du kan lære meget af denne type fyr.


Java tag