Het verschil tussen a.getClass () en A.class in Java

1. Overzicht

In Java, de klas java.lang.Class is het startpunt van alle reflectie-operaties. Zodra we een object van hebben java.lang.Class, kunnen we dan de overeenkomstige methoden aanroepen om de objecten van de reflectieklassen te krijgen.

In deze tutorial bespreken we de verschillen tussen twee verschillende manieren om een ​​object te krijgen java.lang.Class:

  • Bellen met het Object.getClass () methode
  • De ... gebruiken .klasse syntaxis

2. Korte inleiding tot de twee benaderingen

De Object.getClass () methode is een instantiemethode van de Voorwerp klasse. Als we een object hebben, kunnen we bellen object.getClass () om het Klasse object van zijn soort.

Evenzo kunnen we de ClassName.class syntaxis om het Klasse object van het type. Een voorbeeld kan het duidelijk uitleggen:

@Test public void givenObjectAndType_whenGettingClassObject_thenTwoMethodsHaveTheSameResult () {String str = "Ik ben een object van de klasse String"; Klasse fromStrObject = str.getClass (); Class clazz = String.class; assertSame (fromStrObject, clazz); } 

In de bovenstaande testmethode proberen we de Klasse object van de Draad klasse met behulp van de twee manieren die we hebben genoemd. Ten slotte vertelt de assertion-methode ons dat de twee Klasse objecten zijn dezelfde instantie.

Er zijn echter verschillen tussen de twee benaderingen. Laten we ze eens nader bekijken.

3. Het runtime-type versus het statische type

Laten we het vorige voorbeeld snel bekijken. Als we de str.getClass () methode, krijgen we het runtime-type van de str voorwerp. Aan de andere kant, String.class evalueert de Draad klasse statisch. In dit voorbeeld is het runtime-type str en de String.class zijn hetzelfde.

Ze kunnen echter verschillen als klasse-overerving zich bij de party voegt. Laten we twee eenvoudige klassen bekijken:

openbare klasse Animal {protected int numberOfEyes; } public class Monkey breidt Animal {// monkey stuff} uit

Laten we nu een object van de Dier klas en doe nog een test:

@Test openbare leegte gegevenClassInheritance_whenGettingRuntimeTypeAndStaticType_thenGetDifferentResult () {Dierlijk dier = nieuwe aap (); Klasse runtimeType = animal.getClass (); Klasse staticType = Animal.class; assertSame (staticType, runtimeType); } 

Als we de bovenstaande test uitvoeren, krijgen we een testfout:

java.lang.AssertionError: .... Verwacht: class com.baeldung.getclassobject.Animal Actual: class com.baeldung.getclassobject.Monkey

In de testmethode, zelfs als we het dier object door Dierlijk dier = nieuwe aap (); in plaats van Aapdier = nieuwe Aap ();, het runtime-type van het dier object is stil Aap. Dit komt doordat de dier object is een instantie van Aap tijdens runtime.

Wanneer we echter het statische type van het Dier klasse, het type is altijd Dier.

4. Omgaan met primitieve typen

Als we Java-code schrijven, gebruiken we vrij vaak primitieve typen. Laten we proberen een Klasse object van een primitief type met de object.getClass () nadering:

int nummer = 7; Klasse numberClass = number.getClass ();

Als we de bovenstaande code proberen te compileren, krijgen we een compilatiefout:

Fout: java: int kan niet worden verwijderd

De compiler kan het aantal variabele omdat het een primitieve variabele is. Daarom de object.getClass () methode kan ons niet helpen om de Klasse object van een primitief type.

Laten we kijken of we het primitieve type kunnen krijgen met de .klasse syntaxis:

@Test openbare ongeldig gegevenPrimitiveType_whenGettingClassObject_thenOnlyStaticTypeWorks () {Class intType = int.class; assertNotNull (intType); assertEquals ("int", intType.getName ()); assertTrue (intType.isPrimitive ()); } 

We kunnen dus het Klasse object van de int primitief type door int. klasse. In Java-versie 9 en hoger is een Klasse object van primitief type behoort tot de java.base module.

Zoals de test laat zien, de .klasse syntaxis is een gemakkelijke manier om de Klasse object van een primitief type.

5. De klas krijgen zonder een instantie

We hebben geleerd dat de object.getClass () methode kan ons de Klasse object van het runtime-type.

Laten we nu eens kijken naar het geval waarin we een Klasse object van een type, maar we kunnen geen instantie van het doeltype krijgen omdat het een abstract klasse, een koppel, of een bepaalde klasse staat geen instantiatie toe:

openbare abstracte klasse SomeAbstractClass {// ...} interface SomeInterface {// enkele methoden ...} openbare klasse SomeUtils {privé SomeUtils () {gooi nieuwe RuntimeException ("Deze Util-klasse mag niet worden geïnstantieerd!"); } // enkele openbare statische methoden ...} 

In deze gevallen kunnen we de Klasse objecten van die typen die de object.getClass () methode, maar we kunnen nog steeds de .klasse syntaxis om de Klasse voorwerpen van hen:

@Test openbare ongeldig gegevenTypeCannotInstantiate_whenGetTypeStately_thenGetTypesSuccefully () {Class interfaceType = SomeInterface.class; Klasse abstractClassType = SomeAbstractClass.class; Klasse utilClassType = SomeUtils.class; assertNotNull (interfaceType); assertTrue (interfaceType.isInterface ()); assertEquals ("SomeInterface", interfaceType.getSimpleName ()); assertNotNull (abstractClassType); assertEquals ("SomeAbstractClass", abstractClassType.getSimpleName ()); assertNotNull (utilClassType); assertEquals ("SomeUtils", utilClassType.getSimpleName ()); } 

Zoals de bovenstaande test laat zien, is de .klasse syntaxis kan de Klasse objecten voor die typen.

Daarom wanneer we de Klasse object, maar we kunnen geen instantie van het type krijgen, de .klasse syntaxis is de juiste keuze.

6. Conclusie

In dit artikel hebben we twee verschillende manieren geleerd om het Klasse object van een type: de object.getClass () methode en de .klasse syntaxis.

Later bespraken we het verschil tussen de twee benaderingen. De volgende tabel kan ons een duidelijk overzicht geven:

object.getClass ()SomeClass.class
Klasse-objectenHet runtime-type voorwerpHet statische type SomeClass
Primitieve typenWerkt eenvoudig
Interfaces, abstracte klassen of klassen die niet kunnen worden geïnstantieerdWerkt eenvoudig

Zoals altijd is de volledige broncode van het artikel beschikbaar op GitHub.