首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么Java类的编译方式不同,只有一个空行?

为什么Java类的编译方式不同,只有一个空行?
EN

Stack Overflow用户
提问于 2018-10-03 18:35:20
回答 4查看 15.6K关注 0票数 211

我有以下Java类

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

9c8d09e27ea78319ddb85fcf4f8085aa7762b0ab36dc5ba5fd000dccb63960ff  HelloWorld.class

接下来,我修改了类并添加了一个空行,如下所示:

public class HelloWorld {

  public static void main(String []args) {
  }
}

11f7ad3ad03eb9e0bb7bfa3b97bbe0f17d31194d8d92cc683cfbd7852e2d189f  HelloWorld.class

我在this TutorialsPoint article上读到过:

只包含空格的行,可能带有注释,被称为空行,

完全忽略它。

所以我的问题是,既然Java忽略了空行,为什么两个程序的编译字节码是不同的?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-10-03 18:43:14

基本上,行号是为了调试而保留的,所以如果您按照以前的方式更改了源代码,那么您的方法将从不同的行开始,并且编译后的类会反映出不同之处。

票数 335
EN

Stack Overflow用户

发布于 2018-10-03 18:45:54

您可以使用javap -v查看更改,该命令将输出详细信息。与前面提到的其他代码一样,区别在于行号不同:

$ javap -v HelloWorld.class > with-line.txt
$ javap -v HelloWorld.class > no-line.txt
$ diff -C 1 no-line.txt with-line.txt
*** no-line.txt 2018-10-03 11:43:32.719400000 +0100
--- with-line.txt       2018-10-03 11:43:04.378500000 +0100
***************
*** 2,4 ****
    Last modified 03-Oct-2018; size 373 bytes
!   MD5 checksum 058baea07fb787bdd81c3fb3f9c586bc
    Compiled from "HelloWorld.java"
--- 2,4 ----
    Last modified 03-Oct-2018; size 373 bytes
!   MD5 checksum 435dbce605c21f84dda48de1a76e961f
    Compiled from "HelloWorld.java"
***************
*** 50,52 ****
        LineNumberTable:
!         line 3: 0
        LocalVariableTable:
--- 50,52 ----
        LineNumberTable:
!         line 4: 0
        LocalVariableTable:

更准确地说,类文件在LineNumberTable部分有所不同:

LineNumberTable属性是代码属性的属性表中的一个可选的可变长度属性(§4.7.3)。调试器可以使用它来确定代码数组的哪一部分对应于原始源文件中的给定行号。

如果代码属性的属性表中存在多个LineNumberTable属性,则它们可以按任意顺序显示。

在代码属性的属性表中,源文件的每行可能有多个LineNumberTable属性。也就是说,LineNumberTable属性可以一起表示源文件的给定行,并且不需要与源行一对一。

票数 116
EN

Stack Overflow用户

发布于 2018-10-04 19:48:52

"Java忽略空行“的假设是错误的。下面是一段代码片段,它根据方法main之前的空行数不同而表现不同

class NewlineDependent {

  public static void main(String[] args) {
    int i = Thread.currentThread().getStackTrace()[1].getLineNumber();
    System.out.println((new String[]{"foo", "bar"})[((i % 2) + 2) % 2]);
  }
}

如果在main之前没有空行,它将打印"foo",但是在main之前有一个空行时,它将打印"bar"

由于运行时行为不同,因此无论时间戳或其他元数据如何,.class文件都必须不同。

这适用于所有可以访问带有行号的堆栈框架的语言,而不仅仅是Java。

注意:如果它是用-g:none编译的(没有任何调试信息),那么行号将不会包括在内,getLineNumber()总是返回-1,并且程序总是打印"bar",而不管换行符的数量。

票数 58
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52625161

复制
相关文章

相似问题

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