почему существует разница между оригинальным и скомпилированным кодом - PullRequest
4 голосов
/ 20 марта 2011

Здесь я пытался скомпилировать файл Java, и я использовал декомпилятор Java, чтобы проверить скомпилированный код. Почему char преобразуется в int и некоторые имена переменных также изменились?

ORIGINAL JAVA FILE

class CharacterTest{
public static void main(String[] args){

    char t=140; 
    char f='t';
    char p='t';
    System.out.print(t);

}
}

Скомпилированный код

import java.io.PrintStream;

class CharacterTest
{
public static void main(String[] paramArrayOfString)
{
char c = '';
int i = 116;
int j = 116;
System.out.print(c);
}
}

Ответы [ 4 ]

2 голосов
/ 20 марта 2011

JVM и байт-код не различают char и int как таковые.Это только на семантическом / языковом уровне.

И имена второй локальной переменной не содержатся в файле класса.Таким образом, декомпилятор должен придумывать свои собственные имена.

1 голос
/ 20 марта 2011

Это полностью зависит от деталей реализации декомпилятора. Декомпилятор не знает имен и типов ваших локальных переменных, поэтому он должен использовать некоторую эвристику для восстановления его по байт-коду.

Ваш байт-код выглядит следующим образом:

   0:   sipush  140   
   3:   istore_1      
   4:   bipush  116   
   6:   istore_2      
   7:   bipush  116   
   9:   istore_3      

Как видите, 140 рассматривается как константа типа short, тогда как 116 обрабатывается как константа типа byte (это связано с тем, что 116 помещается в байт со знаком , но 140 нет).

Теперь декомпилятор пытается угадать, что это может означать в исходном коде. Похоже, что декомпилятор обрабатывает разницу в типах констант как разницу в типах локальных переменных (также он может использовать сигнатуру print(), выбранную компилятором в качестве подсказки для определения типа t), а имена переменных генерируются в зависимости от по типам (c для char, i и j для int).

Смотри также:

0 голосов
/ 20 марта 2011

Как уже говорилось, локальные переменные для ВМ могут иметь только типы (или, точнее, могут быть доступны с помощью команд для) int, long, float, double и , ссылка - так что все целочисленные типы (кроме long) внутренне обрабатываются как int.

Первая переменная остается char, поскольку это тип аргумента метода println(), вызываемого здесь, поэтому компиляторесть способ угадать это, в то время как две другие переменные больше не используются, поэтому они остаются int здесь.

0 голосов
/ 20 марта 2011

Символ на самом деле является целочисленным типом.

Тип char (символ) содержит один 16-разрядный символ Unicode, который фактически представлен 16-разрядными целыми числами без знака.

(источник: SCJP Кэти Сьерра)

Насчет смены имен, я точно не знаю. Но я думаю, это проблема вашего декомпилятора. Вы пробовали разные декомпиляторы и видели имена переменных, которые все создавали?

...