Čítanie hodnoty „súkromných“ polí z inej triedy v jazyku Java

1. Prehľad

V tomto rýchlom návode si povieme, ako môžeme získať prístup k hodnote a súkromné pole z inej triedy v Jave.

Pred začatím tutoriálu musíme pochopiť, že súkromné modifikátor prístupu zabráni náhodnému zneužitiu polí. Ak k nim však chceme získať prístup, môžeme tak urobiť pomocou rozhrania Reflection API.

2. Príklad

Definujme ukážkovú triedu Osoba s niektorými súkromné polia:

verejná trieda Osoba {private String name = "John"; vek súkromných bajtov = 30; súkromné ​​krátke uidNumber = 5555; private int pinCode = 452002; súkromné ​​dlhé kontaktné číslo = 123456789L; výška súkromného plaváka = 6,1242f; súkromná dvojnásobná hmotnosť = 75,2564; private char gender = 'M'; private boolean active = true; // zakladatelia a zakladatelia}

3. Výroba súkromné Polia sú prístupné

Vyrobiť akýkoľvek súkromné prístupné na poli, musíme zavolať Pole # setAccessible metóda:

Osoba osoba = nová Osoba (); Názov poľaField = person.getClass (). GetDeclaredField ("meno"); nameField.setAccessible (true);

Vo vyššie uvedenom príklade najskôr určíme pole, ktoré chceme načítať - názov - pomocou Trieda # getDeclaredField metóda. Potom pole sprístupníme pomocou nameField.setAccessible (true).

4. Prístup súkromné Primitívne polia

Môžeme prístup k súkromné polia, ktoré sú primitívne pomocou Pole # getXxx metódy.

4.1. Prístup k celočíselným poliam

Môžeme použiť getByte,getShort, dostaťa getLong metódy prístupu k internetu bajt,krátky, inta dlho polia:

@ Test public void whenGetIntegerFields_thenSuccess () vyvolá výnimku {Osoba osoba = nová Osoba (); Pole ageField = osoba.getClass (). GetDeclaredField ("vek"); ageField.setAccessible (true); byte age = ageField.getByte (osoba); Assertions.assertEquals (30, vek); Pole uidNumberField = person.getClass (). GetDeclaredField ("uidNumber"); uidNumberField.setAccessible (true); krátke uidNumber = uidNumberField.getShort (osoba); Assertions.assertEquals (5555, uidNumber); Pole pinCodeField = person.getClass (). GetDeclaredField ("pinCode"); pinCodeField.setAccessible (true); int pinCode = pinCodeField.getInt (osoba); Assertions.assertEquals (452002, pinCode); Pole contactNumberField = person.getClass (). GetDeclaredField ("contactNumber"); contactNumberField.setAccessible (true); dlhé contactNumber = contactNumberField.getLong (osoba); Assertions.assertEquals (123456789L, contactNumber); }

Je tiež možné vykonať autoboxovanie s primitívnymi typmi:

@ Test public void whenDoAutoboxing_thenSuccess () vyvolá výnimku {Osoba osoba = nová Osoba (); Pole pinCodeField = person.getClass (). GetDeclaredField ("pinCode"); pinCodeField.setAccessible (true); Celé číslo pinCode = pinCodeField.getInt (osoba); Assertions.assertEquals (452002, pinCode); }

The getXxx metódy pre primitívne dátové typy tiež podporujú rozšírenie:

@ Test public void whenDoWidening_thenSuccess () vyvolá Výnimku {Osoba osoba = nová Osoba (); Pole pinCodeField = person.getClass (). GetDeclaredField ("pinCode"); pinCodeField.setAccessible (true); Dlhý pinCode = pinCodeField.getLong (osoba); Assertions.assertEquals (452002L, pinCode); }

4.2. Prístup k poliam s pohyblivým typom

Pristúpiť plavák a dvojitý polia, musíme použiť getFloat a getDouble metódy:

@ Test public void whenGetFloatingTypeFields_thenSuccess () vyvolá výnimku {Osoba osoba = nová Osoba (); Pole heightField = osoba.getClass (). GetDeclaredField ("výška"); heightField.setAccessible (true); float height = heightField.getFloat (osoba); Assertions.assertEquals (6.1242f, výška); Pole weightField = osoba.getClass (). GetDeclaredField ("váha"); weightField.setAccessible (true); dvojitá váha = weightField.getDouble (osoba); Assertions.assertEquals (75,2564, hmotnosť); }

4.3. Prístup k poliam znakov

Pre prístup k char polia, môžeme použiť getChar metóda:

@ Test public void whenGetCharacterFields_thenSuccess () vyvolá výnimku {Osoba osoba = nová Osoba (); Pole genderField = osoba.getClass (). GetDeclaredField ("pohlavie"); genderField.setAccessible (true); char gender = genderField.getChar (osoba); Assertions.assertEquals ('M', pohlavie); }

4.4. Prístup k logickým poliam

Podobne môžeme použiť getBoolean metóda prístupu k boolovský lúka:

@ Test public void whenGetBooleanFields_thenSuccess () vyvolá výnimku {Osoba osoba = nová Osoba (); Pole activeField = osoba.getClass (). GetDeclaredField ("aktívne"); activeField.setAccessible (true); boolean active = activeField.getBoolean (osoba); Assertions.assertTrue (aktívne); }

5. Prístup súkromné Polia, ktoré sú objektmi

Môžeme prístup k súkromné polia, ktoré sú objektmi pomocou Pole # dostať metóda. Je potrebné poznamenať, že všeobecné dostať metóda vracia Objekt, takže aby sme mohli hodnotu využiť, musíme ju vložiť do cieľového typu:

@ Test public void whenGetObjectFields_thenSuccess () vyvolá výnimku {Osoba osoba = nová Osoba (); Názov poľaField = person.getClass (). GetDeclaredField ("meno"); nameField.setAccessible (true); Názov reťazca = (Reťazec) nameField.get (osoba); Assertions.assertEquals ("John", meno); }

6. Výnimky

Teraz poďme diskutovať o výnimkách, ktoré môže JVM vyvolať pri prístupe k súkromné polia.

6.1. IllegalArgumentException

JVM bude vhadzovať IllegalArgumentExceptionak použijeme a getXxx prístupový objekt, ktorý je nekompatibilný s typom cieľového poľa. V našom príklade, ak píšeme nameField.getInt (osoba), JVM hodí túto výnimku, pretože pole je typu String a nie int alebo Celé číslo:

@ Test public void givenInt_whenSetStringField_thenIllegalArgumentException () vyvolá výnimku {Person person = new Person (); Názov poľaField = person.getClass (). GetDeclaredField ("meno"); nameField.setAccessible (true); Assertions.assertThrows (IllegalArgumentException.class, () -> nameField.getInt (person)); }

Ako sme už videli, getXxx metódy podporujú rozšírenie pre primitívne typy. Je dôležité si to uvedomiť aby sme boli úspešní, musíme poskytnúť správny cieľ pre rozšírenie. Inak JVM hodí IllegalArgumentException:

@ Test public void givenInt_whenGetLongField_thenIllegalArgumentException () vyvolá výnimku {Person person = new Person (); Pole contactNumberField = person.getClass (). GetDeclaredField ("contactNumber"); contactNumberField.setAccessible (true); Assertions.assertThrows (IllegalArgumentException.class, () -> contactNumberField.getInt (person)); }

6.2. IllegalAccessException

JVM bude hádzať IllegalAccessExceptionak sa snažíme dostať do poľa, ktoré nemá prístupové práva. Vo vyššie uvedenom príklade, ak príkaz nepíšeme nameField.setAccessible (true), potom JVM hodí výnimku:

@ Test public void whenFieldNotSetAccessible_thenIllegalAccessException () vyvolá výnimku {Person person = new Person (); Názov poľaField = person.getClass (). GetDeclaredField ("meno"); Assertions.assertThrows (IllegalAccessException.class, () -> nameField.get (osoba)); }

6.3. NoSuchFieldException

Ak sa pokúsime dostať do poľa, ktoré neexistuje v Osoba triedy, potom mohlo JVM hádzať NoSuchFieldException:

Assertions.assertThrows (NoSuchFieldException.class, () -> person.getClass (). GetDeclaredField ("firstName"));

6.4. NullPointerException

Nakoniec, ako by ste čakali, JVM hodí a NullPointerExceptionak zadáme názov poľa ako nulový:

Assertions.assertThrows (NullPointerException.class, () -> person.getClass (). GetDeclaredField (null));

7. Záver

V tomto návode sme videli, ako môžeme získať prístup k súkromné polia triedy v inej triede. Videli sme aj výnimky, ktoré môže JVM vyvolať, a to, čo ich spôsobuje.

Úplný kód pre tento príklad je ako vždy k dispozícii na serveri GitHub.


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