1. Обзор
В нашем предыдущая статья , Мы обсудили, как мы могли бы прочитать ценности частные поля из другого класса в Java. Однако могут быть сценарии, когда нам нужно установить значения полей, например, в некоторых библиотеках, где у нас нет доступа к полям.
В этом быстром учебнике мы обсудим, как мы можем установить значения полей из другого класса в Java с помощью API отражения.
Обратите внимание, что мы будем использовать то же самое Человек класс для примеров здесь, как мы использовали в наших предыдущая статья .
2. Установка примитивных полей
Мы можем установить поля, которые являются примитивами, используя Полевой наборXxx методы .
2.1. Установка полей интеграторов
Мы можем использовать setByte, наборШорт , s etInt , и setLong методы настройки byte , короткие , int , и долго полей, соответственно:
@Test public void whenSetIntegerFields_thenSuccess() throws Exception { Person person = new Person(); Field ageField = person.getClass() .getDeclaredField("age"); ageField.setAccessible(true); byte age = 26; ageField.setByte(person, age); Assertions.assertEquals(age, person.getAge()); Field uidNumberField = person.getClass() .getDeclaredField("uidNumber"); uidNumberField.setAccessible(true); short uidNumber = 5555; uidNumberField.setShort(person, uidNumber); Assertions.assertEquals(uidNumber, person.getUidNumber()); Field pinCodeField = person.getClass() .getDeclaredField("pinCode"); pinCodeField.setAccessible(true); int pinCode = 411057; pinCodeField.setInt(person, pinCode); Assertions.assertEquals(pinCode, person.getPinCode()); Field contactNumberField = person.getClass() .getDeclaredField("contactNumber"); contactNumberField.setAccessible(true); long contactNumber = 123456789L; contactNumberField.setLong(person, contactNumber); Assertions.assertEquals(contactNumber, person.getContactNumber()); }
Кроме того, можно выполнить Распаковки с примитивными типами:
@Test public void whenDoUnboxing_thenSuccess() throws Exception { Person person = new Person(); Field pinCodeField = person.getClass() .getDeclaredField("pinCode"); pinCodeField.setAccessible(true); Integer pinCode = 411057; pinCodeField.setInt(person, pinCode); Assertions.assertEquals(pinCode, person.getPinCode()); }
S etXxx методы для примитивных типов данных также поддерживают сужение :
@Test public void whenDoNarrowing_thenSuccess() throws Exception { Person person = new Person(); Field pinCodeField = person.getClass() .getDeclaredField("pinCode"); pinCodeField.setAccessible(true); short pinCode = 4110; pinCodeField.setInt(person, pinCode); Assertions.assertEquals(pinCode, person.getPinCode()); }
2.2. Установка плавучих полей типа
Установить поплавок и двойной поля, мы должны использовать установитьFloat и наборДабл методы, соответственно:
@Test public void whenSetFloatingTypeFields_thenSuccess() throws Exception { Person person = new Person(); Field heightField = person.getClass() .getDeclaredField("height"); heightField.setAccessible(true); float height = 6.1242f; heightField.setFloat(person, height); Assertions.assertEquals(height, person.getHeight()); Field weightField = person.getClass() .getDeclaredField("weight"); weightField.setAccessible(true); double weight = 75.2564; weightField.setDouble(person, weight); Assertions.assertEquals(weight, person.getWeight()); }
2.3. Установка полей персонажей
Установить char поля, мы можем использовать setChar метод:
@Test public void whenSetCharacterFields_thenSuccess() throws Exception { Person person = new Person(); Field genderField = person.getClass() .getDeclaredField("gender"); genderField.setAccessible(true); char gender = 'M'; genderField.setChar(person, gender); Assertions.assertEquals(gender, person.getGender()); }
2.4. Установка булеанских полей
Аналогичным образом, мы можем использовать наборБулеан метод настройки булеан поле:
@Test public void whenSetBooleanFields_thenSuccess() throws Exception { Person person = new Person(); Field activeField = person.getClass() .getDeclaredField("active"); activeField.setAccessible(true); activeField.setBoolean(person, true); Assertions.assertTrue(person.isActive()); }
3. Установка полей, которые являются объектами
Мы можем установить поля, которые являются объектами с помощью Полевой набор метод :
@Test public void whenSetObjectFields_thenSuccess() throws Exception { Person person = new Person(); Field nameField = person.getClass() .getDeclaredField("name"); nameField.setAccessible(true); String name = "Umang Budhwar"; nameField.set(person, name); Assertions.assertEquals(name, person.getName()); }
4. Исключения
Теперь давайте обсудим исключения, которые JVM может бросить при настройке полей.
4.1. НезаконноеаргументЭксцепция
СПМ бросит НезаконныеАргументЭксцепция если мы используем setXxx мутатор, несовместимый с типом цели . В нашем примере, если мы пишем nameField.setInt (человек, 26) , JVM бросает это исключение, так как поле имеет тип Струнные а не int или Интегер :
@Test public void givenInt_whenSetStringField_thenIllegalArgumentException() throws Exception { Person person = new Person(); Field nameField = person.getClass() .getDeclaredField("name"); nameField.setAccessible(true); Assertions.assertThrows(IllegalArgumentException.class, () -> nameField.setInt(person, 26)); }
Как мы уже видели, s etXxx методы поддержки сужения для примитивных типов. Важно отметить, что мы должны обеспечить правильную цель для сужения, чтобы быть успешным . В противном случае, JVM бросает НезаконныеАргументЭксцепция :
@Test public void givenInt_whenSetLongField_thenIllegalArgumentException() throws Exception { Person person = new Person(); Field pinCodeField = person.getClass() .getDeclaredField("pinCode"); pinCodeField.setAccessible(true); long pinCode = 411057L; Assertions.assertThrows(IllegalArgumentException.class, () -> pinCodeField.setLong(person, pinCode)); }
4.2. НезаконноеприемкаКцепция
Если мы пытаемся установить частные поле, которое не имеет прав доступа , то JVM будет бросать НезаконныеАцессЭксцепция . В приведеном выше примере, если мы не напишем заявление nameField.setAccessible (правда) , то JVM бросает исключение:
@Test public void whenFieldNotSetAccessible_thenIllegalAccessException() throws Exception { Person person = new Person(); Field nameField = person.getClass() .getDeclaredField("name"); Assertions.assertThrows(IllegalAccessException.class, () -> nameField.set(person, "Umang Budhwar")); }
5. Заключение
В этом учебнике мы видели, как мы можем изменить или установить значения частных полей класса из другого класса в Java. Мы также видели исключения, которые JVM может бросить и что их вызывает.
Как всегда, полный код для этого примера доступен более на GitHub .