java - 兼容反射的设计模式

标签 java reflection

我有一些依赖反射(使用第三方库)来获取类的字段的代码。其中许多类混合使用相同的字段,有些几乎相同,但有一些差异。

这导致了大量的代码重复,但由于依赖反射,我不确定围绕它的良好模式。

根据documentation :

Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object. This includes public, protected, default (package) access, and private fields, but excludes inherited fields.

这排除了抽象类或任何与继承相关的解决方案。

下面是一个代码示例(MyField 表示第三方库对象,myDataMyField 的公共(public)成员):

ClassA.java

public class ClassA {
    private final Field[] myFields;

    private final MyField a = new MyField(1);
    private final MyField b = new MyField(2);
    private final MyField c = new MyField(3);

    public ClassA() {
        myFields = this.getClass().getDeclaredFields();
    }

    public void doStuff(Field[] myFields) {
        // As an example, this clears out the field values.
        // There are several of these methods that use or manipulate the fields
        for (Field f : myFields) {
            if (f.getType() == MyField.class
                || f.getType().getSuperclass() == MyField.class) {
                try {
                    f.setAccessible(true);
                    ((MyField) f.get(this)).myData.reset();
                }
                catch (IllegalArgumentException | IllegalAccessException e) {
                    continue;
                }
            }
        }
    }

    public Field[] getFields() {
        return Arrays.copyOf(myFields, myFields.length);
    {
}

ClassB.java

public class ClassB {
    private final Field[] myFields;

    private final MyField a = new MyField(1);
    private final MyField c = new MyField(3);
    private final MyField d = new MyField(4);

    public ClassB() {
        myFields = this.getClass().getDeclaredFields();
    }

    public void doStuff(Field[] myFields) {
        // Same as above
    }

    public Field[] getFields() {
        return Arrays.copyOf(myFields, myFields.length);
    {
}

请注意,ClassAClassB 共享字段 ac 以及方法 getFields()doStuff()

有什么方法可以在不影响反射的情况下支撑一些重复吗?

最佳答案

为什么类中的字段需要存储在数组中?看来obj.getFields()始终等于 obj.getClass().getDeclaredFields() 。请注意getDeclaredFields无论如何,每次都会返回一个新数组,因此调用它一次,然后在您自己的 getter 上创建一个防御性副本是多余的。

如果您更喜欢 obj.getFields() 的可读性那么你可以将其设为 default interface method ,并从接口(interface)的每个类上继承它,而无需更改类层次结构:

public interface FieldGetter {
    default Field[] getFields() {
        return this.getClass().getDeclaredFields();
    }
}

示例:

> class A implements FieldGetter { int x; String y; }
> new A().getFields()
Field[2] { int A.x, java.lang.String A.y }

目前尚不清楚您的 doStuff 是否方法对每个类执行相同的操作;如果是这样,您也可以将其设为默认接口(interface)方法。

顺便说一下,事实上 getDeclaredFields不返回父类(super class)字段并不是拥有类层次结构的障碍,因为您也可以在父类(super class)上调用它;请参阅this other question .

关于java - 兼容反射的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59291838/

相关文章:

java - 如何在 Ivy 中强制使用 HTTPS?

java - 用Java处理大文件

java - 一台服务器支持多个客户端 Java

java - Google Spreadsheets API 删除下划线

c# - 如何在C#中通过字符串访问类成员?

java - 获取 FinalizedDeleatedExecutorService 的状态

c# - 转换为具有动态类型的集合

java - 指定在 ObjectOutputStream 中(不)序列化哪些字段而不使用 transient 或 serialPersistentFields

scala - 如何在 Scala 中获取动态创建类的完整类名

c# - 可以在没有基类型的情况下使用 C# 约束吗?