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 .