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.