Автоматизированный способ извлечения интерфейсов из Java-класса
У меня есть коллекция конкретных Классов, которые определяют API, и я хотел бы извлечь Интерфейс этих классов (то есть: по существу, иерархию типов и публичные методы) из фактической реализации API.
Так, например, если один из открытых классов в API
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 */
}
Я хотел бы разбить на интерфейс и реализацию
т.е.
public interface FooInterface extends BarInterface {
public void method();
public void otherMethod()
}
public class Foo implements FooInterface {
/* etc etc */
}
а также
Есть ли инструмент, который я могу использовать, чтобы сделать это разделение в автоматическом режиме, или мне придется свернуть свою собственную программу, чтобы сделать работу? Это должен быть инструмент, который требует минимального взаимодействия.
4 ответа
Я нашел решение!
В Eclipse есть поддержка скриптов рефакторинга, скрипты в xml, но не очень удобные для человека, но я все равно сгенерировал скрипты, которые позволяют eclipse выполнять весь рефакторинг.
Подробнее о рефакторинге скрипта eclipse смотрите здесь и используйте eclipse, чтобы сгенерировать несколько примеров, чтобы вы знали, как должен выглядеть скрипт
Многие IDE, например IntelliJ, имеют команду "Извлечь интерфейс", которая выполняет рефакторинг для вас: http://www.jetbrains.com/idea/features/refactoring.html
javap, инструмент в JDK, даст вам большую часть того, что вы хотите. Тем не менее, будьте готовы к тому, что некоторые вещи будут обрабатываться неправильно - извините, я забыл, что, может быть, аннотации, внутренние классы, что-то в этом роде.
Если встраивание javap в ваше собственное Java-приложение поможет, вы можете сделать что-то вроде этого:
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();
}
Это требует Sun JDK tools.jar в пути к классам.
Я почти уверен, что вам придется свернуть свой собственный инструмент, чтобы сделать эту работу; это не то, что многие разработчики использовали бы, и те, кто использовал это, не будут использовать это часто. Извлечение интерфейса, чтобы быть правильным, действительно нуждается в интеллекте (настоящий вид), направляющем его. Инструмент, который извлекает все открытые и защищенные элементы вслепую и слепо выстраивает иерархию интерфейса для отражения иерархии реализации, далеко не умен, и конечный продукт не будет красивым. Развитие (искусственного) интеллекта для принятия правильных решений о том, что включать и что выводить, - это было бы полезным инструментом, но я признаюсь, что для меня это невероятно сложно. То, что предлагают текущие IDE - управляемая помощь - это, вероятно, лучший компромисс. Взбодриться; это значительно менее утомительно, чем делать каждый шаг вручную!