A Java privát mezőinek értékének beolvasása egy másik osztályból

1. Áttekintés

Ebben a gyors bemutatóban megvitatjuk, hogyan érhetjük el az a értékét magán mező egy másik osztályból a Java-ban.

Mielőtt elkezdenénk a bemutatót, meg kell értenünk, hogy a magán a hozzáférés-módosító megakadályozza a mezők véletlenszerű visszaélését. Ha azonban hozzájuk akarunk férni, akkor ezt megtehetjük a Reflection API használatával.

2. Példa

Definiáljunk egy minta osztályt Személy néhánnyal magán mezők:

public class Személy {private String név = "John"; magánbájtos életkor = 30; privát rövid uidNumber = 5555; private int pinCode = 452002; privát hosszú contactNumber = 123456789L; magán úszó magasság = 6.1242f; magán kettős súly = 75,2564; privát char nem = 'M'; privát logikai aktív = igaz; // szerelők és beállítók}

3. Készítés magán Mezők hozzáférhetők

Bármelyik elkészítéséhez magán mező elérhető, hívnunk kell a # Set mezõ Elérhetõ módszer:

Személy személy = új Személy (); Field nameField = person.getClass (). GetDeclaredField ("név"); nameField.setAccessible (true);

A fenti példában először megadjuk a lekérni kívánt mezőt - név - a # GetDeclaredField osztály módszer. Ezután hozzáférhetővé tesszük a mezőt nameField.setAccessible (true).

4. Hozzáférés magán Primitív mezők

Tudunk hozzáférés a magán mezők, amelyek primitívek a # GetXxx mező mód.

4.1. Egész mezők elérése

Használhatjuk a getByte,getShort, getInt, és getLong módszerek a byte,rövid, int, és hosszú mezők, illetve:

@Test public void, amikorGetIntegerFields_thenSuccess () dobja a Kivételt {Person person = new Person (); Field ageField = person.getClass (). GetDeclaredField ("age"); ageField.setAccessible (true); bájt kor = ageField.getByte (személy); Állítások.assertEquals (30, életkor); Mező uidNumberField = person.getClass (). GetDeclaredField ("uidNumber"); uidNumberField.setAccessible (true); rövid uidNumber = uidNumberField.getShort (személy); Assertions.assertEquals (5555, uidNumber); Mező pinCodeField = person.getClass (). GetDeclaredField ("pinCode"); pinCodeField.setAccessible (true); int pinCode = pinCodeField.getInt (személy); Assertions.assertEquals (452002, pinCode); Field contactNumberField = person.getClass (). GetDeclaredField ("contactNumber"); contactNumberField.setAccessible (true); hosszú contactNumber = contactNumberField.getLong (személy); Assertions.assertEquals (123456789L, contactNumber); }

Autoboxolás primitív típusokkal is elvégezhető:

@Test public void, amikor aDoAutoboxing_thenSuccess () dobja a Kivételt {Person person = new Person (); Mező pinCodeField = person.getClass (). GetDeclaredField ("pinCode"); pinCodeField.setAccessible (true); Egész pinCode = pinCodeField.getInt (személy); Assertions.assertEquals (452002, pinCode); }

A getXxx a primitív adattípusok módszerei szintén támogatják a kiszélesítést:

@Test public void, amikor aDoWidening_thenSuccess () kivételt dob ​​{Person person = new Person (); Mező pinCodeField = person.getClass (). GetDeclaredField ("pinCode"); pinCodeField.setAccessible (true); Hosszú pinCode = pinCodeField.getLong (személy); Assertions.assertEquals (452002L, pinCode); }

4.2. Lebegő típusú mezők elérése

Hozzáférni úszó és kettős mezőket, a getFloat és getDouble módszerek, ill.

@Test public void, amikorGetFloatingTypeFields_thenSuccess () dobja a Kivételt {Person person = new Person (); A mező magasságaMező = person.getClass (). GetDeclaredField ("magasság"); heightField.setAccessible (true); úszó magasság = heightField.getFloat (személy); Assertions.assertEquals (6.1242f, magasság); Mező súlyaMező = person.getClass (). GetDeclaredField ("súly"); weightField.setAccessible (true); dupla súly = weightField.getDouble (fő); Állítások.assertEquals (75,2564, súly); }

4.3. Karaktermezők elérése

A char mezőket, használhatjuk a getChar módszer:

@Test public void, amikorGetCharacterFields_thenSuccess () dobja a Kivételt {Személy személy = új Személy (); Field genderField = person.getClass (). GetDeclaredField ("nem"); genderField.setAccessible (true); char nem = genderField.getChar (személy); Assertions.assertEquals ('M', nem); }

4.4. Logikai mezők elérése

Hasonlóképpen használhatjuk a getBoolean módszer a logikai terület:

@Test public void, amikorGetBooleanFields_thenSuccess () dobja a Kivételt {Person person = new Person (); Mező ActiveField = person.getClass (). GetDeclaredField ("aktív"); activeField.setAccessible (true); logikai aktív = activeField.getBoolean (személy); Assertions.assertTrue (aktív); }

5. Hozzáférés magán Objektumok

Tudunk hozzáférés a magán mezők, amelyek objektumok a Mező # get módszer. Meg kell jegyezni, hogy az általános kap módszer visszatér egy Tárgy, ezért az érték kihasználása érdekében át kell adnunk a céltípusra:

@Test public void, amikor aGetObjectFields_thenSuccess () kiveti a (z) {Személy személy = új Személy () kivételt; Field nameField = person.getClass (). GetDeclaredField ("név"); nameField.setAccessible (true); Karakterlánc neve = (String) névField.get (személy); Assertions.assertEquals ("John", név); }

6. Kivételek

Most beszéljük meg azokat a kivételeket, amelyeket a JVM dobhat a magán mezők.

6.1. IllegalArgumentException

A JVM dobni fog IllegalArgumentExceptionha használjuk a getXxx hozzáférés, amely nem kompatibilis a célmező típusával. Példánkban, ha írunk nameField.getInt (személy), a JVM dobja ezt a kivételt, mivel a mező típus Húr és nem int vagy Egész szám:

@Test public void givenInt_whenSetStringField_thenIllegalArgumentException () dobja a Kivételt {Person person = new Person (); Field nameField = person.getClass (). GetDeclaredField ("név"); nameField.setAccessible (true); Assertions.assertThrows (IllegalArgumentException.class, () -> nameField.getInt (személy)); }

Mint már láttuk, a getXxx módszerek támogatják a primitív típusok kiszélesítését. Fontos megjegyezni meg kell adnunk a megfelelő célt, hogy a szélesítés sikeres legyen. Ellenkező esetben a JVM dob egy IllegalArgumentException:

@Test public void givenInt_whenGetLongField_thenIllegalArgumentException () dobja a Kivételt {Személy személy = új Személy (); Field contactNumberField = person.getClass (). GetDeclaredField ("contactNumber"); contactNumberField.setAccessible (true); Assertions.assertThrows (IllegalArgumentException.class, () -> contactNumberField.getInt (személy)); }

6.2. IllegalAccessException

A JVM dobni fog egy IllegalAccessExceptionha olyan mezőhöz próbálunk hozzáférni, amely nem rendelkezik hozzáférési jogokkal. A fenti példában, ha nem írjuk az állítást nameField.setAccessible (true), akkor a JVM dobja a kivételt:

@Test public void whenFieldNotSetAccessible_thenIllegalAccessException () dobja a Kivételt {Személy személy = új Személy (); Field nameField = person.getClass (). GetDeclaredField ("név"); Assertions.assertThrows (IllegalAccessException.class, () -> névField.get (személy)); }

6.3. NoSuchFieldException

Ha megpróbálunk elérni egy nem létező mezőt ban,-ben Személy osztályban, akkor a JVM dobhatott NoSuchFieldException:

Assertions.assertThrows (NoSuchFieldException.class, () -> person.getClass (). GetDeclaredField ("keresztnév"));

6.4. NullPointerException

Végül, ahogy várható volt, a JVM dob egy NullPointerExceptionha a mezőnevet úgy adjuk át nulla:

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

7. Következtetés

Ebben az oktatóanyagban láthattuk, hogyan érhetjük el a magán egy osztály mezői egy másik osztályban. Láttuk azokat a kivételeket is, amelyeket a JVM dobhat, és mi okozza őket.

Mint mindig, ennek a példának a teljes kódja elérhető a GitHubon.


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