我们说我有以下POJO:
public class Student {
private String firstName;
private String lastName;
public Student(){};
public Student(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
及其建造者:
public class StudentBuilder {
private Student student;
public StudentBuilder() {
this.student = new Student();
}
public StudentBuilder withFirstName(String firstName) {
this.student.setFirstName(firstName);
return this;
}
public StudentBuilder withLastName(String lastName) {
this.student.setLastName(lastName);
return this;
}
public Student build() {
return this.student;
}
}
鉴于我有一个Student类的实例,是否有一个库可以将student对象作为参数并返回表示该句子的String,以使用其构建器实例化该特定对象?
用法应该是这样的:
public static void main(String[] args) {
Student student = new Student("John", "Smith");
String builderInstantiator = StringObjectInstantiator.generate(student);
Assert.assertEquals("new StudentBuilder().withFirstName(\"John\").withLastName(\"Smith\").build();", builderInstantiator);
}
我想在开始实施它之前先问一下。
短篇小说: 我正在处理的应用程序的一个模块将为我提供一个包含序列化pojos的json文件。 基于该json,我必须生成一些使用其构建器实例化这些对象的java类。
输入样本:
[
{
"firstName": "John",
"lastName": "Smith"
},
{
"firstName": "David",
"lastName": "Winter"
},
{
"firstName": "Rebecca",
"lastName": "Cross"
}
]
输出样本:
public class StudentProvider {
public List<Student> get() {
return Arrays.asList(
new StudentBuilder().withFirstName("John").withLastName("Smith").build(),
new StudentBuilder().withFirstName("David").withLastName("Winter").build(),
new StudentBuilder().withFirstName("Rebecca").withLastName("Cross").build()
);
}
}
答案 0 :(得分:2)
我认为你可能正在寻找某种代码生成,但我认为不会有库完全符合你的要求。您可以尝试一些构建器生成器,如pojo builder并编辑源代码(或者像Fluent builders这样的eclipse插件。)
除了生成字符串之外,如果对象只包含String,char,int等简单类型,那么生成字符串将很容易。如果你有一个自定义对象,它应该生成什么代码。比方说,如果Student类有一个Object类型的字段,那么需要传递给withXXX()方法的值是什么?如果你能保证所讨论的对象只包含简单的字段,那么编写自己的方法会更好。就像
一样public static String generate(Object obj){
StringBuilder str = new StringBuilder("new " + obj.getClass().getSimpleName() + "()");
Field[] allFields = obj.getClass().getDeclaredFields();
for (Field field : allFields) {
field.setAccessible(true);
try {
str.append(".with").append(capitalize(field.getName())).append("(").append(resolveField(field.get(obj))).append(")");
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return str.append(".build();").toString();
}
注意:这是一个快速的解决方案,可能不是一个理想的解决方案。一个完整的例子
import java.lang.reflect.Field;
class CustomObject {
String innerValue1;
String innerValue2;
public CustomObject(String innerValue1, String innerValue2) {
this.innerValue1 = innerValue1;
this.innerValue2 = innerValue2;
}
public String getInnerValue1() {
return innerValue1;
}
public void setInnerValue1(String innerValue1) {
this.innerValue1 = innerValue1;
}
public String getInnerValue2() {
return innerValue2;
}
public void setInnerValue2(String innerValue2) {
this.innerValue2 = innerValue2;
}
}
class Student {
private String firstName;
private String lastName;
private int sample;
private char sampleChar;
private CustomObject obj;
public Student(){};
public Student(String firstName, String lastName, int sample, char sampleChar, CustomObject obj) {
this.firstName = firstName;
this.lastName = lastName;
this.sample = sample;
this.sampleChar = sampleChar;
this.obj = obj;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getSample() {
return sample;
}
public void setSample(int sample) {
this.sample = sample;
}
public CustomObject getObj() {
return obj;
}
public void setObj(CustomObject obj) {
this.obj = obj;
}
public char getSampleChar() {
return sampleChar;
}
public void setSampleChar(char sampleChar) {
this.sampleChar = sampleChar;
}
}
public class StringObjectInstantiator {
public static String generate(Object obj, boolean appenColon){
StringBuilder str = new StringBuilder("new " + obj.getClass().getSimpleName() + "()");
Field[] allFields = obj.getClass().getDeclaredFields();
for (Field field : allFields) {
field.setAccessible(true);
try {
str.append(".with").append(capitalize(field.getName())).append("(").append(resolveField(field.get(obj))).append(")");
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
str.append(".build()");
return appenColon ? str.append(";").toString() : str.toString();
}
private static String resolveField(Object fieldValue) {
String className = fieldValue.getClass().getSimpleName();
if("String".equals(className)){
return "\"" + fieldValue + "\"";
} else if("Character".equals(className)){
return "'" + fieldValue + "'";
} else if("Number".equals(fieldValue.getClass().getSuperclass().getSimpleName())){
return fieldValue.toString();
} else {
return generate(fieldValue, false);
}
}
private static String capitalize(final String line) {
return Character.toUpperCase(line.charAt(0)) + line.substring(1);
}
public static void main(String[] args) {
System.out.println(generate(new Student("James", "Bond", 2, 'J', new CustomObject("A", "B")), true));
}
}