Rozdiel medzi a.getClass () a A.class v Jave

1. Prehľad

V Jave trieda java.lang.Class je vstupným bodom všetkých reflexných operácií. Akonáhle budeme mať predmet java.lang.Class, potom môžeme zavolať zodpovedajúce metódy na získanie objektov tried reflexie.

V tomto tutoriáli si rozoberieme rozdiely medzi dvoma rôznymi spôsobmi, ako získať predmet java.lang.Class:

  • Volá sa Object.getClass () metóda
  • Pomocou .trieda syntax

2. Krátky úvod k dvom prístupom

The Object.getClass () metóda je inštančná metóda Objekt trieda. Ak máme objekt, môžeme zavolať object.getClass () získať Trieda objekt svojho typu.

Podobne môžeme použiť ClassName.class syntax na získanie súboru Trieda objekt typu. Príklad to môže jasne vysvetliť:

@Test public void givenObjectAndType_whenGettingClassObject_thenTwoMethodsHaveTheSameResult () {String str = "Som objektom triedy String"; Trieda fromStrObject = str.getClass (); Trieda clazz = String.class; assertSame (fromStrObject, clazz); } 

V testovacej metóde vyššie sa snažíme získať Trieda predmet String triedy pomocou dvoch spôsobov, ktoré sme spomenuli. Nakoniec, metóda tvrdenia nám hovorí, že tí dvaja Trieda objekty sú rovnaká inštancia.

Medzi týmito dvoma prístupmi však existujú rozdiely. Pozrime sa na ne bližšie.

3. Runtime typ vs. statický typ

Pozrime sa rýchlo na predchádzajúci príklad. Keď hovoríme str.getClass () metóda, dostaneme runtime typ str objekt. Na druhej strane, Reťazec.trieda hodnotí String trieda staticky. V tomto príklade je to runtime typ str a Reťazec.trieda sú rovnaké.

Môžu sa však líšiť, ak sa na večierok pripojí aj triedne dedičstvo. Pozrime sa na dve jednoduché triedy:

public class Animal {protected int numberOfEyes; } verejná trieda Monkey rozširuje Animal {// monkey things}

Teraz poďme vytvoriť inštanciu objektu Zviera triedy a urobiť ďalší test:

@Test public void givenClassInheritance_whenGettingRuntimeTypeAndStaticType_thenGetDifferentResult () {Zviera zviera = nová Monkey (); Trieda runtimeType = animal.getClass (); Trieda staticType = Animal.class; assertSame (staticType, runtimeType); } 

Ak spustíme test vyššie, dostaneme zlyhanie testu:

java.lang.AssertionError: .... Očakávané: trieda com.baeldung.getclassobject.Animal Actual: trieda com.baeldung.getclassobject.Monkey

V testovacej metóde, aj keby sme vytvorili inštanciu zviera namietať Zvieracie zviera = nová Opica (); namiesto Opičie zviera = nová Opica ();, runtime typ súboru zviera objekt je stále Opica. Je to preto, lebo zviera objekt je inštanciou Opica za behu.

Keď však dostaneme statický typ Zviera trieda, typ je vždy Zviera.

4. Zaobchádzanie s primitívnymi typmi

Keď píšeme Java kód, dosť často používame primitívne typy. Pokúsme sa získať a Trieda objekt primitívneho typu pomocou object.getClass () prístup:

int číslo = 7; Class numberClass = number.getClass ();

Ak sa pokúsime kompilovať vyššie uvedený kód, zobrazí sa nám chyba kompilácie:

Chyba: java: int nemôže byť dereferencovaná

Kompilátor nemôže odradiť číslo premenná, pretože ide o primitívnu premennú. Preto the object.getClass () metóda nám nemôže pomôcť získať Trieda objekt primitívneho typu.

Pozrime sa, či môžeme získať primitívny typ pomocou .trieda syntax:

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

Môžeme teda získať Trieda predmet int primitívny typ cez int.trieda. V prostredí Java verzie 9 a novšej a Trieda objekt primitívneho typu patrí do java.base modul.

Ako ukazuje test, the .trieda syntax je jednoduchý spôsob, ako získať Trieda objekt primitívneho typu.

5. Získanie triedy bez inštancie

Naučili sme sa, že object.getClass () metóda nám môže poskytnúť Trieda objekt svojho typu runtime.

Teraz zvážime prípad, keď chceme získať a Trieda objekt typu, ale nemôžeme získať inštanciu cieľového typu, pretože je to abstraktné trieda, an rozhranie, alebo niektorá trieda neumožňuje vytvorenie inštancie:

verejná abstraktná trieda SomeAbstractClass {// ...} rozhranie SomeInterface {// niektoré metódy ...} verejná trieda SomeUtils {súkromná SomeUtils () {hodiť novú RuntimeException ("Vytvorenie inštancie tejto triedy Util nie je povolené!"); } // niektoré verejné statické metódy ...} 

V týchto prípadoch nemôžeme získať Trieda objekty týchto typov pomocou object.getClass () metóda, ale stále môžeme používať .trieda syntax na získanie súboru Trieda predmety z nich:

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

Ako ukazuje vyššie uvedený test, .trieda syntax môže získať Trieda objekty pre tieto typy.

Preto keď chceme mať Trieda objekt, ale nemôžeme získať inštanciu typu, .trieda cestou je syntax.

6. Záver

V tomto článku sme sa naučili dva rôzne spôsoby, ako získať Trieda objekt typu: object.getClass () metóda a .trieda syntax.

Neskôr sme diskutovali o rozdiele medzi týmito dvoma prístupmi. Nasledujúca tabuľka nám poskytuje jasný prehľad:

object.getClass ()SomeClass.class
Predmety triedyRuntime typ objektStatický typ SomeClass
Primitívne typyFunguje priamo
Rozhrania, abstraktné triedy alebo triedy, ktoré nemožno vytvoriť inštanciouFunguje priamo

Celý zdrojový kód článku je ako vždy k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found