我有一些依赖反射(使用第三方库)来获取类的字段的代码。其中许多类混合使用相同的字段,有些几乎相同,但有一些差异。
这导致了大量的代码重复,但由于依赖反射,我不确定围绕它的良好模式。
根据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
表示第三方库对象,myData
是 MyField
的公共(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);
{
}
请注意,ClassA
和 ClassB
共享字段 a
和 c
以及方法 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/