java - 与反射兼容的设计模式
问题描述
我有一些代码依赖于反射(使用第三方库)来获取类的字段。其中许多类混合使用相同的字段,有些几乎相同,但有一些不同。
这导致了大量的代码重复,但由于依赖反射,我不确定它周围是否有一个好的模式。
根据文档:
返回一个 Field 对象数组,反映由此 Class 对象表示的类或接口声明的所有字段。这包括公共、受保护、默认(包)访问和私有字段,但不包括继承字段。
这排除了抽象类或任何与继承相关的解决方案。
这是一个代码示例(MyField
代表第三方库对象,并且myData
是 的公共成员MyField
):
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()
则可以将其设为默认接口方法,并从接口中的每个类继承它,而无需更改类层次结构:
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
方法是否对每个类都执行相同的操作;如果是这样,您也可以将其设为默认接口方法。
顺便说一句,getDeclaredFields
不返回超类字段的事实并不是拥有类层次结构的障碍,因为您也可以在超类上调用它;看到另一个问题。
推荐阅读
- json - 查找 JSON 中的最高价格
- spring-kafka - 如果没有更多消息,则停止 kafkalistenercontainerfactory
- mysql - 在有子句中使用运算符。错误
- javascript - 无法将类作为函数调用 Javascript
- angular - Angular - 基于 url 中的查询参数的动态样式表呈现
- webstorm - WebStorm 数组包含缺少方法错误
- assembly - SSE XMM 点积说明
- python - 如何在 Python openCV 中显示 16 位 4096 强度图像?
- vba - Excel VBA 过滤被忽略
- dart - Flutter中文本字段中的文本垂直居中