在 Java 中通过反射设置私有字段的最短、最好、最简洁的方法是什么?

问题描述 投票:0回答:4

嗨,我已经使用过 Java 中的 Reflection。但是如果您使用 java 标准(例如注入私有字段),您必须编写大量代码才能完成工作。

在 Java 对象中注入私有字段的最短方法是什么?广泛使用和生产就绪的库中是否有实现?

java reflection
4个回答
18
投票

如果不使用外部库,您需要:

  • 获取
    Field
    实例
  • 将字段实例设置为可访问
  • 设置新值

如下:

Field f1 = obj.getClass().getDeclaredField("field");
f1.setAccessible(true);
f1.set(obj, "new Value");

14
投票

“单线”

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

如果您的项目使用 Apache Commons Lang 通过反射设置值的最短方法是使用类 'org.apache.commons.lang3.reflect.FieldUtils' 中的静态方法 'writeField'

以下简单示例显示了带有 paymentService 字段的 Bookstore-Object。该代码显示了如何使用不同的值两次设置私有字段。

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());
        }
    }
}

您可以通过mavencentral获取lib:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.8.1</version>
</dependency>

3
投票

如果您使用

Spring Framework
,则有一个名为
ReflectionUtils

的 utils 类

这是一种将值注入私有字段的方法。

根据:

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")

如果这是出于测试目的,

ReflectionTestUtils
也为您提供了一些方法。

您可以在文档中找到所有内容这里

希望有帮助。


0
投票

我要做的就是使其成为一个辅助方法。

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");
© www.soinside.com 2019 - 2024. All rights reserved.