2

我正在使用 java 7 update 26。我有一个类,我有一个 while 循环。当我用 jd-gui ( http://java.decompiler.free.fr/?q=jdgui )反编译那个 .class 文件时,它给了我一些奇怪的 while 循环。

try {
  while (true) {
    c = in.read();
    if ((c >= '0' && c <= '9') || c == '-' || c == '+')
    {
      numBuf[len++] = (char) c;
    } else if (c == '.' || c == 'e' || c == 'E') {
      numBuf[len++] = (char) c;
      isFloat = true;
    } else if (c == -1) {
      throw new IOException("EOF");
    } else {
      in.unread(c);
    }
  }
} catch (ArrayIndexOutOfBoundsException e) {
  throw new IOException("Exception with Array ");
}

编译后的版本如下:

try {
  while (true) {
    c = in.read();
    if (((c >= 48) && (c <= 57)) || (c == 45) || (c == 43))
    {
      numBuf[(len++)] = (char)c;
      continue; 
    } 
    if ((c != 46) && (c != 101) && (c != 69))
      break;
    numBuf[(len++)] = (char)c;
    isFloat = true;
  }
  if (c == -1) {
    throw new IOException("EOF");
  }
    in.unread(c);      
} catch (ArrayIndexOutOfBoundsException localArrayIndexOutOfBoundsException) {
    throw new IOException("Exception with Array ");
}

我的代码似乎完全不同..有什么想法吗?

4

5 回答 5

3

'X' 被替换为 ASCII 代码以提高性能。

并且 if/else 更改为 continue/break 以减少比较,仍然是为了性能。

于 2013-08-27T06:44:12.300 回答
2

这是使用使用 Java IL 生成源代码的反编译器的结果。

额外的 '()' 和转换为数字的字符对代码没有影响。

删除else块的更改也是一种优化,因为它不是必需的。

  if (c == -1) {
      throw new IOException("EOF");
    } else {
      in.unread(c);
    }

是相同的

  if (c == -1) {
      throw new IOException("EOF");
   }

   in.unread(c);

因为如果逻辑表达式为真,应用程序将退出。

顺便说一句:您不应该使用Exception来控制应用程序的逻辑。Instaed the while(true)use while(c != -1)then you didn't need that last if

所以代码看起来不同,但工作方式相同。

提示:如果您想诊断代码,请阅读 IL。

于 2013-08-27T07:19:19.227 回答
1

编译后的版本使用字符的 ASCII 值,如果这让你感到困惑的话。反编译的代码没有惊人的变化。

于 2013-08-27T06:40:47.423 回答
1

代码似乎相同。反编译器只是将您的字符更改为他们的 ascii 代码:ascii table

elsif 已被 continue 取代。这是反编译器对字节码的解释

于 2013-08-27T06:42:27.667 回答
0

它刚刚将字符更改为各自的 ASCII 值以获得更好的性能。你可以参考ASCII表

于 2013-08-27T06:41:48.473 回答