Являются ли файлы, декомпилированные JAD, точными на 100%. Я декомпилирую некоторые jar-файлы, чтобы получить исходный код, и когда я пытаюсь собрать проект с этими java-файлами, он не показывает точную сборку. Я делаю это неправильно или декомпилированные файлы не точно такие же, как исходные?
Являются ли декомпилированные JAD-файлы точными на 100 %?
Ответы (2)
Краткий ответ: в 99% случаев декомпилированный код не будет выглядеть как исходный код, но он должен вести себя так же. Таким образом, предполагая, что декомпилятор не делает ошибок, он должен быть точным в работе, но не в реализации.
Длинный ответ: когда компилятор Java переводит ваш исходный код в байтовый код, он выполняет определенные операции, которые изменяют внешний вид кода. Я не эксперт в деталях компилятора Java, но простая оптимизация, которую выполняют многие компиляторы, заключается в вставке небольших методов в то место в коде, где они вызываются.
Например, допустим, мы компилируем этот код:
public class c
{
public int add(int a, int b)
{
return a + b;
}
public static void main(String [] args)
{
int i = add(1, 2);
}
}
Поскольку b — это только одна строка, и ее можно безопасно заменить своим содержимым, умный компилятор может изменить основной метод на это:
public static void main(String [] args)
{
int a = 1, b = 2
int i = a + b;
}
или это:
public static void main(String [] args)
{
int i = 1 + 2;
}
Это было бы сделано, потому что накладные расходы на вызов метода хуже, чем накладные расходы на помещение содержимого метода непосредственно в то место, где он вызывается.
Я понятия не имею, что компилятор Java сделал бы в этой ситуации, но он вносит подобные изменения в код. Это не обязательно неточно, потому что делает то же самое, что и исходный код. Поскольку компилятор не оставляет подробностей об этих изменениях нигде в файле .class, декомпилятор не может узнать, выполнялась ли оптимизация в какой-либо данной точке кода или была ли она написана таким образом.
Есть также ряд других вещей, которые могут не пережить переход на байтовый код (например, имена переменных и комментарии).
Так что да, когда вы смотрите на декомпилированный код, вы смотрите на то, как выглядит файл .class, а не на то, как выглядит файл .java. Несмотря на то, что это кажется неточным, он должен работать так же.
private
, но даже в этом случае он не сделает такого изменения, потому что он должен сохранить структуру класса (например, для случая, когда метод доступ осуществляется через отражение). Встраивание выполняется JIT.
- person Marco13; 16.05.2014
while(a) { if (!b) f(); }
там, где автор изначально написал while(a) { if (b) continue; f(); }
, или a = b ? c : d
там, где автор написал if (b) a = c; else a = d;
. Вы можете увидеть больше промежуточных переменных и встроенных значений. Но вы не должны никогда предполагать, что декомпилированный вывод функционально эквивалентен исходному коду. Так и задумано, но декомпиляторы не безошибочны.
- person Mike Strobel; 16.05.2014
Если в этой программе больше частных занятий. Декомпилятор перевернет код по-своему, но если их меньше, то он покажет правильный код. В случае xml-файлов он преобразует полностью....