有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我正在创建一个util类,它编写.java Files,充当转换生成器

这个util类将生成一个转换器。java'(参考下面的示例)

我想知道如何编写util类。
我在谷歌上搜索,找到了使用ApacheBcel的建议。但是我找不到一个从String编写.java File并在我的程序中运行的示例



期望是

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类生成


共 (2) 个答案

  1. # 1 楼答案

    你可以做很多事情

    你应该准确地决定你想做什么,然后找一个匹配的库来帮你做并学习这个库

    BCEL就是这样一个库。我过去曾成功地将JavaAPT用于类似的目的

    为了您的理解,我将在下面写一些关于生成类的内容,但是请不要自己开发,您很可能会陷入困境

    如果您想让您的类在当前运行的同一JVM中可用(与:您想生成代码,然后再次编译整个程序并重新启动它相反),那么您必须:

    1. 创建文件,将字符串写入其中
    2. 编译文件(这样做的粗略方法是从代码中调用javac)
    3. 将类加载到类加载器中
  2. # 2 楼答案

    你几乎肯定会从尝试用另一种方式来做这件事中获益,这个计划失败的方式之多令人担忧。以下是一些建议:

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

      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
      }
      

      这也可以通过接口实现

    恨你自己™ 评级:

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

    第二种方法在三的中间排列A—3。获得评级是因为您可能偶尔会将一种类型的对象和另一种类型的对象混在一起,并可能产生意外的副作用。如果从代理类中省略setter,则可以将其降低为0,但这会限制功能

    第三种方法得到a-5,这是三种方法中最差的一种。获得评级是因为有很多副作用的可能性,而且多余的代码可能会在以后绊倒你。然而,你可以通过重构所有东西来正确地只使用一个类来达到1级,但是这可能需要大量的工作,你现在会恨自己的

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

    恨你自己™ 等级范围从-10到10,其中10是最大数量的同类,而-10是最大数量的仇恨

    原始答复:

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

    • Showmycode-易于使用,良好的反编译,online(因此不适用于公司材料),搞乱了内置的类名和嵌套的匿名类
    • Jad-downloadable,CLI,可以工作,但会产生难看的代码,linux版本已经过时(如果需要,将windows版本与wine一起使用),导致枚举、foreach循环和一些try/catch出错
    • Fernflower-CLI,很难找到,三者中最好的输出,作者是如此的用户,输出外观不错,有时会搞砸try/catch

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