首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java 8/ Fernflower : Bug或特性

Java 8/ Fernflower : Bug或特性
EN

Stack Overflow用户
提问于 2019-03-08 19:07:30
回答 3查看 1.4K关注 0票数 1

OpenJDK 1.8.0_191

我编译并解压缩了下面的一段代码,使用弗恩弗劳尔。

代码语言:javascript
运行
复制
public class Decompile {
    public static void main(String[] args) {
        final int VAL = 20;
        System.out.println(VAL);
    }
}

产出如下:

代码语言:javascript
运行
复制
public class Decompile {

   public static void main(String[] args) {
      boolean VAL = true;
      System.out.println(20);
   }
}

我很困惑,VAL是怎么变成布尔型的?

更新:

在Intellij中,反编译代码如下所示:

代码语言:javascript
运行
复制
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

public class Decompile {
    public Decompile() {
    }

    public static void main(String[] args) {
        int VAL = true;
        System.out.println(20);
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-03-08 19:17:21

字节码是

代码语言:javascript
运行
复制
L0
 LINENUMBER 5 L0
 BIPUSH 20
 ISTORE 1
L1
 LINENUMBER 6 L1
 GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
 BIPUSH 20
 INVOKEVIRTUAL java/io/PrintStream.println (I)V

如您所见,BIPUSH20推到堆栈上,然后ISTORE获取值并将其存储到局部变量中。

这是一个Fernflower问题。

对于您的兴趣,字节码版本55的输出是

代码语言:javascript
运行
复制
int VAL = true;
System.out.println(20);

您可以看到反编译程序可能是错误的:)

票数 2
EN

Stack Overflow用户

发布于 2019-03-09 02:31:19

根本的问题是Java字节码没有布尔( booleans )、字节(字节)、字符( chars )或短裤(类型签名除外)的概念。所有具有这些类型的局部变量都被编译为ints。布尔值true和false分别编译为10

这意味着反编译器必须猜测给定的局部变量是布尔型还是整数型。在这种情况下,值20存储在变量中,该变量将永远不会存储在Java代码中的布尔类型变量中,因此反编译器应该很容易猜测它是基于上下文的整数类型。但弗劳尔的布尔猜测似乎并不那么复杂。

就其价值而言,这是一个固有的难题。特别是当您考虑到非Java字节码不需要遵循与Java相同的模式时。字节码在整数和布尔上下文中使用相同的变量是完全有效的。对于猜测变量是否应该是布尔人,克拉卡托反编译器有一个相当复杂的推断步骤,但在这种情况下,它仍然会出错。

票数 1
EN

Stack Overflow用户

发布于 2019-03-08 19:12:01

它的工作方式就像compiler在生成byte code期间做一些optimization一样。因为VAL = 20;是最终的,并且不会更改,所以它可以将20替换为VAL,而不需要impacting第二个语句中的功能。现在,decompiler只有byte code,当它读取拜特代码时,它在second line中找到了内联的20。由代码生成的字节代码如下:

代码语言:javascript
运行
复制
   0: bipush        20
   2: istore_1
   3: getstatic     #20                 // Field java/lang/System.out:Ljava/io/PrintStream;
   6: bipush        20
   8: invokevirtual #26                 // Method java/io/PrintStream.println:(I)V
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55069491

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档