从另一个方法动态初始化 POJO
Initialize a POJO dynamically from another method
假设我有这些实现接口的 POJO class 集,但这里没有公共属性。
public interface MainIfc {}
class Ifc1 implements MainIfc {
private String a1;
public String getA1() {
return a1;
}
public void setA1(String a1) {
this.a1 = a1;
}
}
class Ifc2 implements MainIfc {
private String x1;
private String x2;
public String getX1() {
return x1;
}
public void setX1(String x1) {
this.x1 = x1;
}
public String getX2() {
return x2;
}
public void setX2(String x2) {
this.x2 = x2;
}
}
结合这些 POJO classes,我有几个方法可以用来检索基于另一个值 returned 的 POJO 类型和具有值的实际 POJO .
public class GetIfc {
public Class getIfcType(int code) {
if (code==1)
return Ifc1.class;
else
return Ifc2.class;
}
public MainIfc getIfc(int code) {
if (code==1) {
Ifc1 thisIfc = new Ifc1();
thisIfc.setA1("Ifc1");
return thisIfc;
} else {
Ifc2 thisIfc = new Ifc2();
thisIfc.setX1("Ifc2");
thisIfc.setX2("Ifc2");
return thisIfc;
}
}
}
有没有一种方法可以在我的代码中安全地读取具体的 POJO 并使用 getters/setters?我已经回答了很多问题,这些问题提供了基于反射的答案,但这对我不起作用。 getters/setters 不可见,当我在 returned 对象上调用 .getClass()
时,我看到它是 MainIfc
接口。
我试图解决的设计问题与我试图设计的 REST API 自动化框架有关。基本上我有一个 ClientResponse
解析器,它会发回我正在寻找的 POJO。但我不希望编写测试用例的人担心 returned 的 POJO 类型。所以我想我可以 return 类型和实例化的 POJO,所以我得到了值,但我对如何动态实现这个感到困扰。
试试这个代码。也许这将 return class 中的所有方法以及从 Object
class.
继承的方法
public static void main(String[] args) throws ClassNotFoundException {
GetIfc getIfc=new GetIfc();
MainIfc clas1s=getIfc.getIfc(1);
Class class1= clas1s.getClass();
System.out.println(class1);
Method[] mem= class1.getMethods();
for(Method mmm : mem) {
System.out.println(mmm.getName());
}
}
在我看来,您似乎在尝试做一些不合逻辑的事情。 Strategy Pattern 或 Abstract Factory 可能很适合你的要求,但目前我不太明白你到底想达到什么目的。你绝对不应该在这些 类 上有条件地转换和调用不同的方法。如果您真的想继续走这条路,我建议您进行反思,如果不是一个选项,并且您需要灵活性,我可能会选择某种地图。
但如果可能的话,我肯定会重新考虑您的设计。
试试这段代码,我不知道我是否完全理解你的要求,但根据我的理解,我认为下面的代码可以解决问题。
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
GetIfc getIfc = new GetIfc();
MainIfc clas1s = getIfc.getIfc(1);
Field[] fields = clas1s.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
Class fieldClasslasse = field.getType();
if (field.getModifiers() == Modifier.PRIVATE) {
// you need to check fieldClass, if it is boolean then initials of the getter could be 'is' instead of 'get'
String methodNameGet = "get" + Character.toUpperCase(field.getName().charAt(0))
+ field.getName().substring(1);
String methodNameSet = "set" + Character.toUpperCase(field.getName().charAt(0))
+ field.getName().substring(1);
Method methodGet = clas1s.getClass().getDeclaredMethod(methodNameGet, null);
Object value = methodGet.invoke(clas1s, null);
if (value != null && value instanceof String) {
String valueUpper = ((String)value).toUpperCase();
Class[] cArg = new Class[1];
cArg[0] = String.class;
Method methodSet = clas1s.getClass().getDeclaredMethod(methodNameSet, cArg);
Object[] var = new Object[1];
var[0] = valueUpper;
methodSet.invoke((Object) clas1s, var);
}
}
}
}
关于上面代码的一点解释:获取对象的所有字段并检查是否是私有的 属性,如果是,则它必须具有 public getter 和 setter,根据 java 约定猜测他们的名字,调用 getter,获取值,检查它是否是 String class 的实例,如果是,则将其设为大写,然后调用setter 设置新值。
MainIfc 的使用者真的需要 POJO,还是只需要其中的数据?
如果 MainIfc 声明一个或两个公开其消费者需要的数据的方法,设计可能会更简洁。然后您的 POJO 可以实现 MainIfc 接口声明的方法。或者您可以为每个符合接口的 POJO 构建一个包装器 class,如果您希望将接口实现与 POJO 分开。
理想情况下,接口应该公开一些方法,这些方法可用于与实现它的任何 class 进行交互,并且没有人需要了解底层 POJOs/implementation.
public interface MainIfc {
public Hash getAttributes();
public setAttributes(Hash attributes);
}
class Ifc1 implements MainIfc {
private String a1;
public String getA1() {
return a1;
}
public void setA1(String a1) {
this.a1 = a1;
}
public Hash getAttributes() {
// return a hash with data that MainIfc consumer will need from this POJO
}
public setAttributes(Hash attributes) {
// copy hash attributes to corresponding POJO fields
}
}
class Ifc2 implements MainIfc {
private String x1;
private String x2;
public String getX1() {
return x1;
}
public void setX1(String x1) {
this.x1 = x1;
}
public String getX2() {
return x2;
}
public void setX2(String x2) {
this.x2 = x2;
}
public Hash getAttributes() {
// return a hash with data that MainIfc consumer will need from this POJO
}
public setAttributes(Hash attributes) {
// copy hash attributes to corresponding POJO fields
}
}
假设我有这些实现接口的 POJO class 集,但这里没有公共属性。
public interface MainIfc {}
class Ifc1 implements MainIfc {
private String a1;
public String getA1() {
return a1;
}
public void setA1(String a1) {
this.a1 = a1;
}
}
class Ifc2 implements MainIfc {
private String x1;
private String x2;
public String getX1() {
return x1;
}
public void setX1(String x1) {
this.x1 = x1;
}
public String getX2() {
return x2;
}
public void setX2(String x2) {
this.x2 = x2;
}
}
结合这些 POJO classes,我有几个方法可以用来检索基于另一个值 returned 的 POJO 类型和具有值的实际 POJO .
public class GetIfc {
public Class getIfcType(int code) {
if (code==1)
return Ifc1.class;
else
return Ifc2.class;
}
public MainIfc getIfc(int code) {
if (code==1) {
Ifc1 thisIfc = new Ifc1();
thisIfc.setA1("Ifc1");
return thisIfc;
} else {
Ifc2 thisIfc = new Ifc2();
thisIfc.setX1("Ifc2");
thisIfc.setX2("Ifc2");
return thisIfc;
}
}
}
有没有一种方法可以在我的代码中安全地读取具体的 POJO 并使用 getters/setters?我已经回答了很多问题,这些问题提供了基于反射的答案,但这对我不起作用。 getters/setters 不可见,当我在 returned 对象上调用 .getClass()
时,我看到它是 MainIfc
接口。
我试图解决的设计问题与我试图设计的 REST API 自动化框架有关。基本上我有一个 ClientResponse
解析器,它会发回我正在寻找的 POJO。但我不希望编写测试用例的人担心 returned 的 POJO 类型。所以我想我可以 return 类型和实例化的 POJO,所以我得到了值,但我对如何动态实现这个感到困扰。
试试这个代码。也许这将 return class 中的所有方法以及从 Object
class.
public static void main(String[] args) throws ClassNotFoundException {
GetIfc getIfc=new GetIfc();
MainIfc clas1s=getIfc.getIfc(1);
Class class1= clas1s.getClass();
System.out.println(class1);
Method[] mem= class1.getMethods();
for(Method mmm : mem) {
System.out.println(mmm.getName());
}
}
在我看来,您似乎在尝试做一些不合逻辑的事情。 Strategy Pattern 或 Abstract Factory 可能很适合你的要求,但目前我不太明白你到底想达到什么目的。你绝对不应该在这些 类 上有条件地转换和调用不同的方法。如果您真的想继续走这条路,我建议您进行反思,如果不是一个选项,并且您需要灵活性,我可能会选择某种地图。
但如果可能的话,我肯定会重新考虑您的设计。
试试这段代码,我不知道我是否完全理解你的要求,但根据我的理解,我认为下面的代码可以解决问题。
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
GetIfc getIfc = new GetIfc();
MainIfc clas1s = getIfc.getIfc(1);
Field[] fields = clas1s.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
Class fieldClasslasse = field.getType();
if (field.getModifiers() == Modifier.PRIVATE) {
// you need to check fieldClass, if it is boolean then initials of the getter could be 'is' instead of 'get'
String methodNameGet = "get" + Character.toUpperCase(field.getName().charAt(0))
+ field.getName().substring(1);
String methodNameSet = "set" + Character.toUpperCase(field.getName().charAt(0))
+ field.getName().substring(1);
Method methodGet = clas1s.getClass().getDeclaredMethod(methodNameGet, null);
Object value = methodGet.invoke(clas1s, null);
if (value != null && value instanceof String) {
String valueUpper = ((String)value).toUpperCase();
Class[] cArg = new Class[1];
cArg[0] = String.class;
Method methodSet = clas1s.getClass().getDeclaredMethod(methodNameSet, cArg);
Object[] var = new Object[1];
var[0] = valueUpper;
methodSet.invoke((Object) clas1s, var);
}
}
}
}
关于上面代码的一点解释:获取对象的所有字段并检查是否是私有的 属性,如果是,则它必须具有 public getter 和 setter,根据 java 约定猜测他们的名字,调用 getter,获取值,检查它是否是 String class 的实例,如果是,则将其设为大写,然后调用setter 设置新值。
MainIfc 的使用者真的需要 POJO,还是只需要其中的数据?
如果 MainIfc 声明一个或两个公开其消费者需要的数据的方法,设计可能会更简洁。然后您的 POJO 可以实现 MainIfc 接口声明的方法。或者您可以为每个符合接口的 POJO 构建一个包装器 class,如果您希望将接口实现与 POJO 分开。
理想情况下,接口应该公开一些方法,这些方法可用于与实现它的任何 class 进行交互,并且没有人需要了解底层 POJOs/implementation.
public interface MainIfc {
public Hash getAttributes();
public setAttributes(Hash attributes);
}
class Ifc1 implements MainIfc {
private String a1;
public String getA1() {
return a1;
}
public void setA1(String a1) {
this.a1 = a1;
}
public Hash getAttributes() {
// return a hash with data that MainIfc consumer will need from this POJO
}
public setAttributes(Hash attributes) {
// copy hash attributes to corresponding POJO fields
}
}
class Ifc2 implements MainIfc {
private String x1;
private String x2;
public String getX1() {
return x1;
}
public void setX1(String x1) {
this.x1 = x1;
}
public String getX2() {
return x2;
}
public void setX2(String x2) {
this.x2 = x2;
}
public Hash getAttributes() {
// return a hash with data that MainIfc consumer will need from this POJO
}
public setAttributes(Hash attributes) {
// copy hash attributes to corresponding POJO fields
}
}