我正在创建一个util类,它编写充当coverer-generator的.java Files
。
这个util类将生成AConverter.java'(请参阅下面的示例)
我想知道如何编写util类。
我在谷歌上搜索了一下,找到了使用apache bcel的建议。但我找不到一个从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类生成。
你几乎肯定会从尝试用不同的方式来做这件事中受益,这个方案可能失败的方式之多令人担忧。以下是一些建议:
-
添加某种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个,每个类派生一个。
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 }
-
与其尝试制作适配器,不如合并这些类。可以通过以下方式轻松完成:
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 }
这也可以通过接口来实现。
恨自己以后™评级:
第一种方法排名为2,是三种方法中最好的一种。获得评级是因为你永远不会发现自己意外地在两者之间切换,也不需要更改太多其他代码。
第二种方法排名为-3,在这三种方法中处于中间位置。之所以获得评分,是因为你们可能偶尔会混淆一种类型的物体和另一种类型,并可能产生意想不到的副作用。如果从代理类中省略setter,则可以将其降低为0,但这会限制功能。
第三种方法得到-5分,是三种方法中最差的一种。获得评级是因为有很多副作用的可能性,而多余的代码可能会在以后绊倒你。然而,您可以通过重构所有内容以正确地只使用一个类来获得1,但这可能需要大量的工作,而且您现在会因此而憎恨自己。
也就是说,你最初的想法是动态生成一个类,在两个等级之间转换大约为-10,因为它将非常难以维护,并且对底层类的任何变化都非常敏感,而且可能很容易被打破。
恨自己以后™评分范围从-10到10,其中10是最大的喜欢量,-10是最大的仇恨量。
原始答案:
你想要一个反编译器。有几个java反编译器可供选择,我将列出几个:
- Showmycode-易于使用、良好的反编译、在线(因此不适合公司材料)、内置类名和嵌套匿名类
- Jad-可下载,CLI,可以工作,但会产生难看的代码,linux版本已经过时(如果需要,可以使用wine的windows版本),破坏了enum、foreach循环和一些try/catchs
- Fernflower-CLI,很难找到,是三个中最好的输出,作者是SO用户,输出看起来不错,有时会搞砸尝试/捕获
它们都不是完美的,但这只是因为一些数据在编译过程中丢失了,反编译器必须猜测程序最初的样子。
您可以做多种事情。
你应该准确地决定你想做什么,然后找到一个匹配的库,为你做并学习该库。
BCEL就是这样一个图书馆。我过去曾成功地将Java APT用于类似的目的。
为了便于理解,我将在下面写一些关于生成类的内容,但请不要自己开发,你很可能会陷入困境。
如果你想让你的类在你当前运行的JVM中可用(与之相反:你想生成代码,然后重新编译整个程序并重新启动它),那么你必须:
- 创建文件,将字符串写入其中
- 编译文件(一种粗略的方法是从代码中调用javac)
- 将类加载到类加载器中