访问 class 的字段,哪些 getter 是私有的
Accessing the fields of a class which getters are private
假设我有一个 class 这样的:
public final class Identity {
private String name;
private String nin;
private int age;
}
我想获取 class 中字段的值,其中 getter 是私有的。到目前为止,除了创建一个通用 Object[] 数组并将每个字段的值存储在其中之外,我没有想出任何解决方案。像这样:
public Object[] getFields() {
fields = new Object[]{getName(), getNin(), getAge()};
return(fields);
}
这实际上是一个糟糕的解决方案吗?我读过类型转换通常是糟糕编程的标志,我可能应该重新考虑我的策略,但我没有看到任何潜在的缺点,因为:我确切地知道我的 class 中有多少字段,我知道它们在数组中的确切位置,我确切地知道它们每个的数据类型。例如,如果我想访问字段 age,我知道它将位于数组的位置 2 (Object[2] ) 并且我知道它将是 int 类型,因此我必须将其转换为 int.
我欢迎任何想法。
注意:我应该提一下,要求方法的 setter 和 getter 不能被另一个干扰 class 访问,因此它们被声明为私有的。此外,在我的程序中,class 正在实现这样的接口:
public interface Attribute {
// Fills the fields of the class with the data the user wants to.
void fill ( );
void view ( );
// Edits one or more of the fields of the class with the data the user wants to.
void edit ( );
String toString ( );
}
如您所见,它没有定义任何 setter 和 getter。 getFields() 方法通常会在接口中声明,如果它被认为是一个不错的解决方案,当然。
不管是不是最好的设计,看来你可以使用反射:
import java.lang.reflect.Field;
public MyClass {
String getName(Identity identity) {
return getStringFieldValue(identity, "name");
}
String getNin(Identity identity) {
return getStringFieldValue(identity, "nin");
}
int getAge(Identity identity) {
return getIntFieldValue(identity, "age");
}
String getStringFieldValue(Identity identity, String fieldName) {
try {
Field field = identity.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return (String) field.get(identity);
} catch (NoSuchFieldException e) {
return "";
} catch (IllegalAccessException e) {
return "";
}
}
int getIntFieldValue(Identity identity, String fieldName) {
try {
Field field = identity.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return (int) field.get(identity);
} catch (NoSuchFieldException e) {
return -1;
} catch (IllegalAccessException e) {
return -1;
}
}
}
我想我已经让这个问题悬而未决很久了。事实证明,正如@shmosel 指出的那样,答案非常微不足道。我需要做的就是将 class 的 getter 设置为 public(setter 仍将保持私有,我的想法是我希望 class 中的字段可见但是不能被任何不相关的 class) 修改,并对 class 进行转换。像这样:
Identity identity = (Identity) attribute;
String name = identity.getName();
String nin = identity.getNin();
int age = identity.getAge();
就是这样。正如我所说的,这是非常微不足道的事情。
假设我有一个 class 这样的:
public final class Identity {
private String name;
private String nin;
private int age;
}
我想获取 class 中字段的值,其中 getter 是私有的。到目前为止,除了创建一个通用 Object[] 数组并将每个字段的值存储在其中之外,我没有想出任何解决方案。像这样:
public Object[] getFields() {
fields = new Object[]{getName(), getNin(), getAge()};
return(fields);
}
这实际上是一个糟糕的解决方案吗?我读过类型转换通常是糟糕编程的标志,我可能应该重新考虑我的策略,但我没有看到任何潜在的缺点,因为:我确切地知道我的 class 中有多少字段,我知道它们在数组中的确切位置,我确切地知道它们每个的数据类型。例如,如果我想访问字段 age,我知道它将位于数组的位置 2 (Object[2] ) 并且我知道它将是 int 类型,因此我必须将其转换为 int.
我欢迎任何想法。
注意:我应该提一下,要求方法的 setter 和 getter 不能被另一个干扰 class 访问,因此它们被声明为私有的。此外,在我的程序中,class 正在实现这样的接口:
public interface Attribute {
// Fills the fields of the class with the data the user wants to.
void fill ( );
void view ( );
// Edits one or more of the fields of the class with the data the user wants to.
void edit ( );
String toString ( );
}
如您所见,它没有定义任何 setter 和 getter。 getFields() 方法通常会在接口中声明,如果它被认为是一个不错的解决方案,当然。
不管是不是最好的设计,看来你可以使用反射:
import java.lang.reflect.Field;
public MyClass {
String getName(Identity identity) {
return getStringFieldValue(identity, "name");
}
String getNin(Identity identity) {
return getStringFieldValue(identity, "nin");
}
int getAge(Identity identity) {
return getIntFieldValue(identity, "age");
}
String getStringFieldValue(Identity identity, String fieldName) {
try {
Field field = identity.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return (String) field.get(identity);
} catch (NoSuchFieldException e) {
return "";
} catch (IllegalAccessException e) {
return "";
}
}
int getIntFieldValue(Identity identity, String fieldName) {
try {
Field field = identity.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return (int) field.get(identity);
} catch (NoSuchFieldException e) {
return -1;
} catch (IllegalAccessException e) {
return -1;
}
}
}
我想我已经让这个问题悬而未决很久了。事实证明,正如@shmosel 指出的那样,答案非常微不足道。我需要做的就是将 class 的 getter 设置为 public(setter 仍将保持私有,我的想法是我希望 class 中的字段可见但是不能被任何不相关的 class) 修改,并对 class 进行转换。像这样:
Identity identity = (Identity) attribute;
String name = identity.getName();
String nin = identity.getNin();
int age = identity.getAge();
就是这样。正如我所说的,这是非常微不足道的事情。