问题
I am creating a util-class which writes .java Files
that act as coverter - generator.
This util-class will generate AConverter.java' (refer below sample)
I want know how to write the util-class.
I googled, and found the recommendation to use apache bcel. But I couldn't find an example to write the .java File
from a String
and have it working in my program.
The expectation is...
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;
}
}
The above class AConverter will generated by the new Util-class.
回答1:
You would almost certainly benefit from trying to do this a different way, the number of ways this scheme could fail is worryingly large. Here are some suggestions:
Add a caster method of some sort:
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; } }
A proxy class, perhaps a subclass of the intended class. You would need 2, one derived from each class.
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 }
Rather than trying to make an adapter, merge the classes. Could be easily accomplished with the following:
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 }
This could also be done with interfaces.
HateYourselfLater™ Ratings:
The first method ranks a 2, the best of the three. Rating earned because you won't ever find yourself accidentally switching between the two and not much other code has to be changed.
The second method ranks a -3, in the middle of the three. Rating earned because you may occasionally mix up objects that are of one type of the other, with possible unintended side effects. You can reduce this to a rating of 0 if you omit setters from the proxy classes, but this limits functionality.
The third method gets a -5, the worst of the three. Rating earned because there is a lot of possibility for side effects and the redundant code will probably trip you up later. However, you can make rate 1 by refactoring everything to properly use only one class, but that might take a lot of work, and you'll hate yourself for it now.
That said, your original idea of generating a class on the fly to convert between the two ranks about a -10 because it will be horribly difficult to maintain and very sensitive to any changes of the underlying classes, and will probably be easy to break.
HateYourselfLater™ Scale ranges from -10 to 10, with 10 being the largest amount of like, and -10 being the largest amount of hate.
Original Answer:
You want a decompiler. There are several java decompilers available to pick from, I'll list a few:
- Showmycode - easy to use, decent decompiling, online (thus unsuitable for corporate material), screws up built in class names and nested anonymous classes
- Jad - downloadable, CLI, works but produces ugly code, linux version is out of date (use windows version with wine if necessary) , screws up enums, foreach loops, and some try/catches
- Fernflower - CLI, hard to find, best output of the three, author is SO user, decent looking output, screws up try/catches sometimes
None of them are perfect, but that's just a result of the fact that some data gets lost during compilation, and decompilers must guess what the program originally looked like.
回答2:
You can do multiple things.
You SHOULD decide what you want to do precisely and then get a matching library do it for you and learn that library.
BCEL is one such library. I've used Java-APT in the past successfully for similar purposes.
For your understanding I will write some things about generating classes below, but please, don't develop this yourself, you most likely will end up stuck.
If you want to have your class available within the same JVM you are currently running (in opposition to: you want to generate code and then compile the whole program again and restart it) then you have to:
- Create the File, write your String to it.
- Compile the File (a rough way to do so would call javac from the code)
- load the classes into your classloader.
来源:https://stackoverflow.com/questions/11762080/how-to-create-java-file-programmatically