Декомпиляция и перекомпиляция класса Java

У меня есть программа, в которой доступны некоторые классы Java. Можно их декомпилировать? Можно ли изменить исходный код класса и перекомпилировать его, не имея всех остальных .class файлов?

Например, предположим, что у меня есть файл dog.class, реализующий подкласс животных, определенный в animal.class.

  • Могу ли я перекомпилировать dog.java без animal.class?
  • Могу ли я перекомпилировать dog.java без animal.java?

Я не разработчик Java, поэтому, пожалуйста, поправьте меня, если я не понимаю смысла.


person shodanex    schedule 13.06.2009    source источник


Ответы (6)


Вам понадобится файл class, чтобы фактически использовать класс, но это не значит, что вам понадобится исходный файл.

Давайте рассмотрим возможности на примере классов Dog и Animal. Предполагая, что класс Dog является подклассом класса Animal, мы можем сделать следующее:

  • Если у вас есть и Animal.class, и Animal.java, вы можете создать класс Dog.

  • Если у вас есть Animal.class, но нет Animal.java, вы можете создать класс Dog.

  • Если у вас нет Animal.class, но есть Animal.java, вы можете создать класс Dog. (Это означает, что файл Animal.java нужно будет компилировать вместе с файлом Dog.java.)

  • Если у вас нет ни Animal.class, ни Animal.java, вы не можете создать класс Dog.

Вот табличная версия вышеизложенного:

 Have Animal.java?     Have Animal.class?       Can make Dog class?
 -----------------     ------------------       -------------------
        Yes                    Yes          -->          Yes
        Yes                    No           -->          Yes
        No                     Yes          -->          Yes
        No                     No           -->          No

Если у вас есть файл class, существуют программы, которые могут декомпилировать файл class для создания удобочитаемого исходного файла java, однако он не восстановит точный исходный код, который использовался для создания файла class.

Однако в этом случае, если все, что необходимо, — это расширить класс Animal, чтобы создать новый класс Dog, сам исходный код не нужен.

Имейте это в виду — всякий раз, когда класс создается на Java, он всегда расширяет класс Object. Даже если у нас нет доступа к исходному коду класса Object, поскольку у нас есть доступ к Object.class в Java, мы можем создавать свои собственные классы.

Этот случай аналогичен — пока у нас есть файл class для класса, мы можем использовать его в полной мере. Единственное, чего не хватает, так это фактической реализации, которая указана в исходном коде.

person coobird    schedule 13.06.2009

В общем, нет. Однако вы можете сделать заглушки для этих отсутствующих классов (только для компиляции), а затем заменить их оригиналом, когда они у вас есть.

person Alex Taylor    schedule 13.06.2009

Если у вас есть доступ к скомпилированному классу (animal.class в вашем примере), вы можете перекомпилировать подкласс (dog.java) (однако вам не нужно иметь доступ к исходному коду надкласса).

Если у вас даже нет доступа к скомпилированному суперклассу, то, если вы знаете соответствующие методы (те, которые реализованы или вызываются из подкласса), вы можете создать заглушку суперкласса только для того, чтобы компилировать подкласс.

Однако в какой-то момент вам понадобится реальная версия скомпилированного суперкласса, чтобы ваш код мог выполняться правильно...

person Matthew Murdoch    schedule 13.06.2009

Просто чтобы добавить к другим ответам, один аспект, на который вам, возможно, придется обратить внимание, заключается в том, что если ваш класс имеет сложную структуру, декомпилятор может быть не в состоянии декомпилировать его до «перекомпилируемого» состояния, и вам может потребоваться отредактировать его вручную.

person talonx    schedule 13.06.2009

Если вы можете запустить класс и декомпилировать его, то у вас есть необходимые классы для компиляции исправленного файла Java (если вы включите их в свой путь к классам).

Обратите внимание, что ваш новый файл класса должен находиться «перед» исходными классами в пути к классам, чтобы он вступил в силу.

Также обратите внимание, что «запечатанные jar-файлы» не позволяют этому трюку изменять классы.

person Thorbjørn Ravn Andersen    schedule 13.06.2009
comment
Вам не нужны другие классы для декомпиляции. - person shodanex; 13.06.2009

Мои 2 цента: некоторые декомпиляторы предотвращают декомпиляцию классов на физическом уровне (например, вы получите сбой во время процесса декомпиляции на некоторых декомпиляторах). Дополнительная проблема, с которой я столкнулся при использовании декомпиляторов, лишь немногие из них поддерживают аннотации. В моем случае, когда я пытаюсь декомпилировать класс, я получаю тупик: код содержит аннотацию, но может быть декомпилирован без сбоя только с помощью декомпилятор, не поддерживающий аннотации.

person FoxyBOA    schedule 15.06.2009