Автоматизированный способ извлечения интерфейсов из 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 - управляемая помощь - это, вероятно, лучший компромисс. Взбодриться; это значительно менее утомительно, чем делать каждый шаг вручную!

Другие вопросы по тегам