java - 如何以编程方式创建java文件

标签 java reflection code-generation bcel

我正在创建一个实用程序类,它写入充当转换生成器的 .java 文件

这个实用程序类将生成 AConverter.java'(引用下面的示例)

我想知道如何编写 util 类。
我用谷歌搜索,找到了使用 apache bcel 的建议。但我找不到从 String 编写 .java 文件 并让它在我的程序中工作的示例。



期望是...

class ADTO
{
    private String empId;
    private String empName;
    private String dept;

    //setters and getters
}

class ABO
{
    private String loginId;
    private String userName;
    private String group;

    //setter and getter
}

class AConverter
{
    public void doConvertFromDB(ADTO source, ABO dest)
    {
        dest.setLoginId(source.getEmpId());
        ...
    }

    public void doConvertFromBO(ABO source, ADTO dest)
    {
        dest.setEmpId(source.getLoginId());
        ...

    public ADTO getSourceClass()
    {
        return ADTO.class;
    }

    public ABO getDestClass()
    {
        return ABO.class;
    }
}

上面的类 AConverter 将由新的 Util 类生成。

最佳答案

您几乎肯定会从尝试以不同的方式做到这一点中受益,该方案可能失败的方式数量之多令人担忧。以下是一些建议:

  1. 添加某种类型的施法者方法:

    class ADTO
    {
        private String empId;
        private String empName;
        private String dept;
    
        // setters and getters
    
        public ABO toABO() // caster method (ABO will need a toADTO() as well)
        {
            ABO a = new ABO();
    
            a.setSomething(getSomethingEquivalent());
            ...
    
            return a;
        }
    }
    
  2. 代理类,可能是目标类的子类。您需要 2 个,每个类派生一个。

    class ADTO_Proxy extends ADTO
    {
        private ABO abo;
    
        public ADTO_Proxy(ABO a)
        {
            super();
            abo = a;
        }
    
        @override
        public String getEmployeeId()
        {
            return abo.getLoginId();
        }
    
        // other setters and getters
    }
    
  3. 与其尝试创建适配器,不如合并类。可以通过以下方式轻松完成:

    class ADTO
    {
        private String empId;
        private String empName;
        private String dept;
    
        // getters and setters for each variable by each name
        public String getEmployeeId()
        { return empId; }
        public String getLoginId()
        { return empId; }
    
        public String getEmployeeName()
        { return empName; }
        public String getUsername()
        { return empName; }
    
        public String getDepartment()
        { return dept; }
        public String getGroup()
        { return dept; }
    
        // setters
    }
    

    这也可以通过接口(interface)来完成。

HateYourselfLater™ 评分:

第一种方法排名为 2,是三种方法中最好的。获得评级是因为您永远不会发现自己意外地在两者之间切换,并且不需要更改太多其他代码。

第二种方法的排名为 -3,位于三种方法的中间。获得评级是因为您有时可能会混淆一种类型的对象和另一种类型的对象,从而可能产生意想不到的副作用。如果您从代理类中省略 setter,则可以将其降低为 0,但这会限制功能。

第三种方法的得分为 -5,是三种方法中最差的。之所以获得评级,是因为很可能会产生副作用,而且冗余代码可能会在以后给您带来麻烦。然而,您可以通过重构所有内容以仅正确使用一个类来获得速率 1,但这可能需要大量工作,而且您现在会因此讨厌自己。

也就是说,您最初的想法是动态生成一个类,以便在两个等级之间进行大约 -10 的转换,因为它将非常难以维护,并且对底层类的任何更改非常敏感,并且可能很容易打破。

HateYourselfLater™ 量表范围从 -10 到 10,其中 10 表示点赞量最大,-10 表示仇恨量最大。

原始答案:

你想要一个反编译器。有几种 java 反编译器可供选择,我将列出一些:

  • Showmycode - 易于使用,良好的反编译,online (因此不适合企业 Material ),搞砸内置类名和嵌套匿名类
  • Jad - 可下载,CLI,可以工作,但会产生丑陋的代码,Linux 版本已过时(如果需要,请使用带有 wine 的 Windows 版本),搞砸了枚举、foreach 循环和一些 try/catch
  • Fernflower - CLI,很难找到,三者中最好的输出,作者是 SO 用户,看起来不错的输出,有时会搞砸 try/catch

它们都不是完美的,但这只是编译过程中丢失一些数据的结果,反编译器必须猜测程序最初的样子。

关于java - 如何以编程方式创建java文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11762080/

相关文章:

java - Android AltBeacon 后台服务测距

go - 基于字符串动态创建对象

c# - 使用表达式树调用不安全方法

scala - 无法从 "Full Configuration"生成带有 SBT 0.11 的源代码

design-patterns - IntelliJ 中的构建器模式代码生成

c++ - 通过继承减少模板膨胀

java - 主线程运行顺序

java - 如何迭代缓存条目

java - 在新 Intent 上填充 ArrayList

reflection - 如何检查一个类是否属于 Java JDK