【问题标题】:Dynamic class creation with Fields from other classes使用其他类的字段动态创建类
【发布时间】:2019-04-21 20:20:32
【问题描述】:

例子:

public class MyObject{
    @SerializedName("hello")
    @NotNull @MaxLength(256) @NotEmpty
    private String hello;
}

public class MyOtherObject{
    @SerializedName("world")
    @NotNull @MaxLength(512) @NotEmpty
    private String world;
}

如何动态生成一个 MyDynamicHelloWorldObject 类,使其等效于:

public class MyDynamicHelloWorldObject{
    @SerializedName("hello")
    @NotNull @MaxLength(256) @NotEmpty
    private String hello;

    @SerializedName("world")
    @NotNull @MaxLength(512) @NotEmpty
    private String world;
}

寻找解决方案,因为复制和粘贴会导致错误,尤其是在将来更改代码时。

【问题讨论】:

  • 这个问题来自XY problem。您不是在描述您想要解决的问题,而是您认为应该应用的解决方案,但没有任何细节或背景信息。该解决方案很可能是错误的,或者至少是非常糟糕的设计。可能聚合是解决这个问题的更好方法,但是我只能推测出这么少的信息。我读到这里的感觉是:“哇,这真是个坏主意!”
  • 你认为它是XY,因为你不明白它可以用来做什么。问问自己,在 model/dao/dto/whatever 中为同一事物声明了多少次变量。哪个是糟糕的设计?让它自动化还是不得不一次又一次地重写所有内容?现在想想当有大量注释时会发生什么。现在想想当代码更新时会发生什么。你的感觉不对,你不知道发生了什么。
  • 不,因为你没有解释什么是 XY,因此我(或其他任何人)无法理解你想要实现的目标。你刚刚证明它是XY!因为你不解释,所以每个人都“不知道发生了什么”,正如你所说的那样。所以谢谢你开始解释。但这还不够,在您解释了一下之后,我仍然认为您的想法很糟糕:(待续)
  • 如果动态生成一个类,那么使用那个类的代码是从哪里来的呢?它也必须生成或必须使用反射。即使你有它的源代码,如果它使用的类还不存在,它应该编译什么?我了解您想避免使用样板代码,但这是错误的方法。一种想法可能是使用 APT(注释处理)来进行代码生成。无论如何,这仍然是猜测,没有完整的MCVE 显示您希望如何使用生成的代码。
  • MCVE 已经存在。我想创建一个新类,其中包含我想要的任何字段以及在原始类中声明的注释,这样我就不必在许多类中维护同一个变量的多个副本。我不在乎它是怎么做的,只关心它是动态的,并且可以达到使最终结果等效的目标。从你的回复中我可以看出,自己做。很好。

标签: java reflection aop


【解决方案1】:

不确定是否推荐的方式。您可以通过组合以下两个文件来创建文件 MyDynamicHelloWorldObject.java,

String fileName1 = "MyObject.java";
String fileName2 = "MyOtherObject.java";

//read and write with try-with-resources
try (Stream<String> stream1 = Files.lines(Paths.get(fileName1));
    Stream<String> stream2 = Files.lines(Paths.get(fileName2));
    BufferedWriter writer1 = new BufferedWriter(new FileWriter("MyDynamicHelloWorldObject.java"))) {

    //first line 
    writer1.write("public class MyDynamicHelloWorldObject{\n");
    //merge two streams and skip first line as it has class name
    Stream.concat(stream1.skip(1),stream2.skip(1)).forEach(line->{try {
        writer1.write(line+"\n");
    } catch (IOException e) {
        //error handling
    }});
} catch (IOException e) {
    //error handling
}
}

【讨论】:

    猜你喜欢
    • 2012-08-03
    • 2019-04-29
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    相关资源
    最近更新 更多