Какой самый короткий, лучший, самый чистый способ установить личное поле с помощью Reflection в Java? - PullRequest
0 голосов
/ 12 декабря 2018

Привет, я уже работал с Reflection в Java.Но если вы используете стандарты Java (например, добавление частного поля), вам нужно написать много кода, чтобы выполнить работу.

Каков самый короткий способ внедрения частного поля в объекте Java?Есть ли реализации в широко используемых и готовых к работе библиотеках?

Ответы [ 4 ]

0 голосов
/ 12 декабря 2018

Если вы используете Spring Framework, существует класс утилит с именем ReflectionUtils

. Вот способ вставить значение в приватное поле.

Согласно:

findField(Class<?> clazz, String name, Class<?> type)

и

setField(Field field, @Nullable Object target, @Nullable Object value)

Вы можете написать:

final Field field = ReflectionUtils.findField(Foo.class, "name", String.class)
ReflectionUtils.setField(field, targetObject, "theNewValue")

Это, конечно, не самый короткийМожно написать это, но это короче, чем базовые инструменты JDK, и я доверяю людям, которые разрабатывают Spring, поэтому я достаточно уверен.Просто убедитесь, что вы действительно нуждаетесь в рефлексии, прежде чем делать это.

Плюс, если это для целей тестирования, есть ReflectionTestUtils, который также предоставляет вам несколько методов.

Вы найдете всев документах здесь

Надеюсь, это поможет.

0 голосов
/ 12 декабря 2018

Без использования внешних библиотек вам необходимо:

  • получить Field экземпляр
  • установить экземпляр поля как доступный
  • установить новое значение

Как следует:

Field f1 = obj.getClass().getDeclaredField("field");
f1.setAccessible(true);
f1.set(obj, "new Value");
0 голосов
/ 12 декабря 2018

я бы сделал вспомогательный метод.

public static void changeField(Class cc, String field, String newValue) throws NoSuchFieldException, IllegalAccessException {
    Field f = cc.getDeclaredField(field);
    f.setAccessible(true);
    f.set(cc, newValue);
    f.setAccessible(false);
}

и вызвал бы его следующим образом

changeField(cc, "field", "newValue");
0 голосов
/ 12 декабря 2018

«Однострочник»

FieldUtils.writeField(Object target, String fieldName, Object value, boolean forceAccess)

Если в вашем проекте используется Apache Commons Lang , самый короткий способ установить значение с помощью отражения - это использоватьстатический метод 'writeField' в классе 'org.apache.commons.lang3.reflect.FieldUtils'

В следующем простом примере показан объект Bookstore-Object сПоле оплатыService.Код показывает, как частное поле устанавливается два раза с другим значением.

import org.apache.commons.lang3.reflect.FieldUtils;

public class Main2 {
    public static void main(String[] args) throws IllegalAccessException {
        Bookstore bookstore = new Bookstore();

        //Just one line to inject the field via reflection
        FieldUtils.writeField(bookstore, "paymentService",new Paypal(), true);
        bookstore.pay(); // Prints: Paying with: Paypal

        //Just one line to inject the field via reflection
        FieldUtils.writeField(bookstore, "paymentService",new Visa(), true);
        bookstore.pay();// Prints Paying with: Visa
    }

    public static class Paypal implements  PaymentService{}

    public static class Visa implements  PaymentService{}

    public static class Bookstore {
        private  PaymentService paymentService;
        public void pay(){
            System.out.println("Paying with: "+ this.paymentService.getClass().getSimpleName());
        }
    }
}

Вы можете получить библиотеку через maven central:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.8.1</version>
</dependency>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...