如果出现Unknown Source这样的问题,估计是编译的时候debug设置的false。
Unknown Source,顾名思义,就是未知的源文件。因为我们最终解释运行的是class文件,所以出现这个问题的原因很简单,就是class文件中没有源文件的相关调试信息。那为什么class文件会没有调试信息呢?答案更简单,当然是我们在用javac命令进行编译的时候没有指定调试信息呗。因为现在很多人都习惯用eclipse等一些现成的ide进行编写代码,所以很少人熟悉jdk自己的javac,java,jdb等一些命令的详细参数(jdk的一些命令和eclipse自带的一些命令可能不同)。哈哈,不过如果你经常在linux下玩java的话,命令肯定会非常熟悉。那么让我们看看javac的一些重要参数:
-g-Generate all debugging information, including local variables. By default, only line number and source file information is generated.在class文件中生成所有调试信息,包括局部变量的信息。默认的话,只写入源码的行号和源文件信息。
-g:none-Do not generate any debugging information.不生成任何调试信息。
-g:(lines,vars,source)-只生成部分调试信息(源码行号,变量,源文件信息)。那我们在分别介绍下lines,vars,source的含义。
lines:将源文件中的行号信息写到Class文件中,此属性用于在Class文件中生成方法字节码流偏移量和源代码行号之间的映射关系。如果我们不指定此属性的话,我们将在堆栈异常信息中看不到打印的行号。
vars:Local variable属性建立了方法的栈帧中局部变量部分内容与源代码中局部变量名称和描述符之间的映射关系。有了这个属性,调试时,我们才可以看到变量的值。
source:编译时指定了这个属性,会把源文件的属性信息如源文件名称写入class文件。
说了这么多,初学者可能会迷糊,为什么编译要指定这些调试信息呢?哈哈,如果编译不指定这些调试信息的话,你怎么调试呢?如果你不指定行号信息的话,你在ide中都无法插入断点。这些调试信息在我们调试程序的时候非常重要。不过这些编译选项通常在ide中如eclipse中早已默认了。有的人可能还不相信,打开eclipse,依次打开菜单选项:Window->Preferences->Java->Compiler,可以看到页面的下方有一个Classfile Generation,默认是四个选项都选的。
那这个Unknown Source到底是编译的时候没有指定哪一项呢?经过测试,我发现是javac编译的时候没有指定source选项,必定出Unknown Source这个问题。
问题例子:
1、建立目录,结构如下
2、Hello.java
package com.ex;
public class Hello
{ public static void main(String[] args)
{
System.out.println("Hello world!!"); // Person p = new Person();
Person p = null;
p.sayHello();
}
}
3、Person.java
package com.ex;
public class Person
{
private String name = "David";
public Person()
{
System.out.println("Person construct");
} public void sayHello()
{
System.out.println(name + " say Hello!");
}
}
4、KnownSource_compile.bat
:: -g 生成所有调试信息
::javac -d classes -g src\com\ex\Hello.java src\com\ex\Person.java
:: -g
javac -d classes -g src\com\ex\Hello.java src\com\ex\Person.java
pause
5、UnknownSource_compile.bat
javac -d classes -g:none src\com\ex\Hello.java src\com\ex\Person.java
pause