Automated way to Extract Interfaces from a Java Class
I've got a collection of concrete Classes which define an API, and I would like to extract the Interface of these classes (ie: essentially the type hierarchy and public methods) from the actual implementation of the API.
So for example if one of the public classes in the API开发者_StackOverflow中文版 is
public class Foo extends Bar {
/* some fields which I don't care about */
public void method() {
/* implementation here */
}
public void otherMethod() {
/* implementation goes here */
}
/* some non public methods which I don't care about */
}
I would like to break into an interface and an implementation
ie
public interface FooInterface extends BarInterface {
public void method();
public void otherMethod()
}
public class Foo implements FooInterface {
/* etc etc */
}
and
Is there a tool I can use to do this separation in automated way, or am I going to have to roll my own program to do the job? It needs to be a tool that requires minimal interaction.
I found the solution!
Eclipse, has support for refactoring scripts, the scripts are in xml yet not very human friendly but I have generated the scripts anyway that makes eclipse perform all the refactoring.
For details of eclipse script refactoring, look here and use eclipse to generate a few examples for you so you know what the script should look like
Many IDEs, like IntelliJ, have an "Extract Interface" command which performs a refactoring for you: http://www.jetbrains.com/idea/features/refactoring.html#Extract_Interface
javap, a tool in the JDK, will get you most of what you want. However, be prepared for it to not handle some things correctly - sorry, I forget what, maybe annotations, inner classes, something like that.
If embedding javap in you own Java app would help, you can do something like this:
import sun.tools.javap.Main;
...
void javap(String className) throws IOException
{
bos = new ByteArrayOutputStream();
ourOut = new PrintStream(bos);
PrintStream oldOut = System.out;
System.setOut(ourOut);
String[] params = new String[] {"-public", className};
Main.main(params);
System.setOut(oldOut);
String str = bos.toString();
}
This requires the Sun JDK tools.jar in the classpath.
I'm pretty sure you'll have to roll your own tool to do this job; it's not something that many developers would use, and those who did use it wouldn't use it often. Extract Interface, to be done right, really needs intelligence (the real kind) guiding it. A tool that blindly extracted all public & protected elements, and blindly built an interface hierarchy to mirror an implementation hierarchy, is far from smart, and the end product wouldn't be pretty. Developing the (artificial) intelligence to make good decisions about what to include and what to lead out - that would be a useful tool, but I confess unimaginably difficult for me. What current IDEs offer - guided assistance - is probably the best compromise. Cheer up; it's massively less tedious than doing every step by hand!
精彩评论