Forskjellen mellom a.getClass () og A.class i Java

1. Oversikt

I Java, klassen java.lang.Klasse er inngangspunktet for alle refleksjonsoperasjoner. Når vi har et objekt av java.lang.Klasse, kan vi da kalle de tilsvarende metodene for å få gjenstandene til refleksjonsklassene.

I denne opplæringen vil vi diskutere forskjellene mellom to forskjellige måter å få et objekt på java.lang.Klasse:

  • Ringer til Object.getClass () metode
  • Bruker .klasse syntaks

2. Kort introduksjon til de to tilnærmingene

De Object.getClass () metoden er en forekomstmetode for Gjenstand klasse. Hvis vi har et objekt, kan vi ringe object.getClass () å få Klasse objekt av sin type.

På samme måte kan vi bruke ClassName.class syntaks for å få Klasse objekt av typen. Et eksempel kan forklare det tydelig:

@Test offentlig ugyldighet givenObjectAndType_whenGettingClassObject_thenTwoMethodsHaveTheSameResult () {String str = "Jeg er et objekt av String-klassen"; Klasse fromStrObject = str.getClass (); Class clazz = String.class; assertSame (fromStrObject, clazz); } 

I testmetoden ovenfor prøver vi å få tak i Klasse gjenstand for String klasse på de to måtene vi har nevnt. Til slutt forteller påstandsmetoden oss at de to Klasse objekter er den samme forekomsten.

Imidlertid er det forskjeller mellom de to tilnærmingene. La oss se nærmere på dem.

3. Runtime-typen vs. den statiske typen

La oss se gjennom det forrige eksemplet raskt. Når vi kaller str.getClass () metoden, får vi kjøretidstypen av str gjenstand. På den andre siden, Strengklasse evaluerer String klasse statisk. I dette eksemplet, kjøretidstypen str og Strengklasse er det samme.

De kan imidlertid være forskjellige hvis klassearv blir med på festen. La oss se to enkle klasser:

offentlig klasse Animal {protected int numberOfEyes; } offentlig klasse Monkey utvider Animal {// monkey stuff}

La oss nå instantiere et objekt av Dyr klasse og gjør en ny test:

@Test offentlig ugyldighet givenClassInheritance_whenGettingRuntimeTypeAndStaticType_thenGetDifferentResult () {Animal animal = new Monkey (); Class runtimeType = animal.getClass (); Klasse staticType = Animal.class; assertSame (staticType, runtimeType); } 

Hvis vi kjører testen ovenfor, får vi en testfeil:

java.lang.AssertionError: .... Forventet: klasse com.baeldung.getclassobject.Animal Faktisk: klasse com.baeldung.getclassobject.Monkey

I testmetoden, selv om vi instantierte dyr innvende av Dyredyr = ny ape (); i stedet for Monkey animal = new Monkey ();, kjøretidstypen til dyr objektet er fortsatt Ape. Dette er fordi dyr objekt er en forekomst av Ape ved kjøretid.

Imidlertid når vi får den statiske typen av Dyr klasse, er typen alltid Dyr.

4. Håndtering av primitive typer

Når vi skriver Java-kode, bruker vi primitive typer ganske ofte. La oss prøve å få en Klasse objekt av en primitiv type ved hjelp av object.getClass () nærme seg:

int tall = 7; Class numberClass = number.getClass ();

Hvis vi prøver å kompilere koden ovenfor, får vi en kompileringsfeil:

Feil: java: int kan ikke refereres til

Kompilatoren kan ikke referere til Nummer variabel siden den er en primitiv variabel. Derfor, de object.getClass () metoden kan ikke hjelpe oss å få Klasse objekt av en primitiv type.

La oss se om vi kan få den primitive typen ved hjelp av .klasse syntaks:

@Test offentlig ugyldig givenPrimitiveType_whenGettingClassObject_thenOnlyStaticTypeWorks () {Class intType = int.class; assertNotNull (intType); assertEquals ("int", intType.getName ()); assertTrue (intType.isPrimitive ()); } 

Så vi kan få tak i Klasse gjenstand for int primitiv type gjennom int.klasse. I Java versjon 9 og senere, a Klasse objekt av primitiv type tilhører java.base modul.

Som testen viser, de .klasse syntaks er en enkel måte å få Klasse objekt av en primitiv type.

5. Å få klassen uten et tilfelle

Vi har lært at object.getClass () metoden kan gi oss Klasse objekt av kjøretidstype.

La oss nå vurdere saken der vi ønsker å få en Klasse objekt av en type, men vi kan ikke få en forekomst av måltypen fordi den er en abstrakt klasse, en grensesnitt, eller noen klasse tillater ikke instantiering:

offentlig abstrakt klasse SomeAbstractClass {// ...} grensesnitt SomeInterface {// noen metoder ...} offentlig klasse SomeUtils {private SomeUtils () {kaste ny RuntimeException ("Denne Util-klassen er ikke tillatt å bli instantiert!"); } // noen offentlige statiske metoder ...} 

I disse tilfellene kan vi ikke få Klasse gjenstander av disse typene ved hjelp av object.getClass () metode, men vi kan fortsatt bruke .klasse syntaks for å oppnå Klasse gjenstander av dem:

@Test offentlig ugyldighet givenTypeCannotInstantiate_whenGetTypeStatically_thenGetTypesSuccefully () {Class interfaceType = SomeInterface.class; Class abstractClassType = SomeAbstractClass.class; Class utilClassType = SomeUtils.class; assertNotNull (interfaceType); assertTrue (interfaceType.isInterface ()); assertEquals ("SomeInterface", interfaceType.getSimpleName ()); assertNotNull (abstractClassType); assertEquals ("SomeAbstractClass", abstractClassType.getSimpleName ()); assertNotNull (utilClassType); assertEquals ("SomeUtils", utilClassType.getSimpleName ()); } 

Som testen ovenfor viser, er .klasse syntaksen kan få Klasse gjenstander for disse typene.

Derfor, når vi vil ha Klasse objekt, men vi kan ikke få en forekomst av typen, den .klasse syntaks er veien å gå.

6. Konklusjon

I denne artikkelen lærte vi to forskjellige måter å få Klasse objekt av en type: den object.getClass () metoden og .klasse syntaks.

Senere diskuterte vi forskjellen mellom de to tilnærmingene. Følgende tabell kan gi oss en klar oversikt:

object.getClass ()SomeClass.class
KlassegjenstanderKjøretidstypen av gjenstandDen statiske typen SomeClass
Primitive typerFungerer greit
Grensesnitt, abstrakte klasser eller klasser som ikke kan instantiseresFungerer greit

Som alltid er hele kildekoden til artikkelen tilgjengelig på GitHub.