我有这个目录c:\abcd
它没有文件,但有一个子目录efgh。
C:\abcd>dir
Volume in drive C has no label.
Volume Serial Number is B411-D580
Directory of C:\abcd
02/08/2014 06:57 PM <DIR> .
02/08/2014 06:57 PM <DIR> ..
02/08/2014 07:01 PM <DIR> efgh
0 File(s) 0 bytes
3 Dir(s) 1,990,201,344 bytes free
如您所见,efgh子目录有3个文件。 Blah.java
,Greeter.java
和comb.java
Blah.java
有一个班级,Greeter.java
有一个班级。
comb.java
恰好包含Blah.java
和Greeter.java
的代码,因此它有两个类。它是多余的,但它是为了展示一些东西。这是一个梳子编译的情况,而其中一个单独的文件(Blah.java
)没有。
C:\abcd>cd efgh
C:\abcd\efgh>dir
Volume in drive C has no label.
Volume Serial Number is B411-D580
Directory of C:\abcd\efgh
02/08/2014 07:01 PM <DIR> .
02/08/2014 07:01 PM <DIR> ..
02/08/2014 07:00 PM 130 Blah.java
02/08/2014 07:00 PM 216 comb.java
02/08/2014 07:00 PM 99 Greeter.java
3 File(s) 445 bytes
2 Dir(s) 1,990,201,344 bytes free
这些是三个文件的内容
C:\abcd\efgh>type Blah.java
package efgh;
class Blah {
Greeter greeter = new Greeter();
public static void main(String[] args) {}
}
C:\abcd\efgh>type Greeter.java
package efgh;
class Greeter {
public static void main(String[] args) {}
}
C:\abcd\efgh>type comb.java
package efgh;
class Blah {
Greeter greeter = new Greeter();
public static void main(String[] args) {}
}
class Greeter {
public static void main(String[] args) {}
}
C:\abcd\efgh>javac comb.java
所以,comb.java编译。
我看到它生成了Blah.class
和Greeter.class
,这进一步证明了它已编译,但我现在将删除这些.class
文件。这就是我的意思,javac comb.java
有效。
C:\abcd\efgh>dir
Volume in drive C has no label.
Volume Serial Number is B411-D580
Directory of C:\abcd\efgh
02/08/2014 07:02 PM <DIR> .
02/08/2014 07:02 PM <DIR> ..
02/08/2014 07:02 PM 341 Blah.class
02/08/2014 07:00 PM 130 Blah.java
02/08/2014 07:00 PM 216 comb.java
02/08/2014 07:02 PM 261 Greeter.class
02/08/2014 07:00 PM 99 Greeter.java
5 File(s) 1,047 bytes
2 Dir(s) 1,990,201,344 bytes free
C:\abcd\efgh>del *.class
现在我将单独编译它们。并且它不能很好地工作..编译Blah.java
会产生错误。
C:\abcd\efgh>dir
Volume in drive C has no label.
Volume Serial Number is B411-D580
Directory of C:\abcd\efgh
02/08/2014 07:03 PM <DIR> .
02/08/2014 07:03 PM <DIR> ..
02/08/2014 07:00 PM 130 Blah.java
02/08/2014 07:00 PM 216 comb.java
02/08/2014 07:00 PM 99 Greeter.java
3 File(s) 445 bytes
2 Dir(s) 1,990,201,344 bytes free
C:\abcd\efgh>javac Greeter.java
C:\abcd\efgh>javac Blah.java
Blah.java:5: error: cannot find symbol
Greeter greeter = new Greeter();
^
symbol: class Greeter
location: class Blah
Blah.java:5: error: cannot find symbol
Greeter greeter = new Greeter();
^
symbol: class Greeter
location: class Blah
2 errors
我知道技术上,我的类路径设置不正确。因为,由于我没有设置classpath变量,因此它默认为当前目录的类路径。并且给定包名称,类路径应为c:\abcd
。如果我将其设置为那么它会单独编译blah.java
。
C:\abcd\efgh>javac -cp c:\abcd Blah.java
但这仍然无法解释为什么comb.java在没有开关的情况下编译得很好:
C:\abcd\efgh>javac comb.java
C:\abcd\efgh>
我理解comb.java
中的包语句适用于Blah
类和Greeter
类。编译comb.java
时我不明白为什么我不需要特别设置类路径,而我在编译javac Blah.java
时也这样做。
答案 0 :(得分:3)
您已经完成了所有分析,最后一点非常简单:comb.java
任何类路径都是因为它完全是自包含的:{{1从Greeter
引用的文件存在于同一文件中。
通常,Blah
需要在编译类A时查阅类路径,类A引用类B,在传递给它的文件列表中不。
例如,尝试javac
,它也可以正常工作。
答案 1 :(得分:2)
您正在编译而没有为编译器指定输出“root”以构建包层次结构 - 因此它只是将类文件放在与源文件相同的目录中。然后它尝试稍后查找类,但它无法在efgh
包中找到类,因为您已经在efgh
目录中并且没有正确设置类路径。 / p>
选项:
从源根编译:
c:\abcd> javac efgh\Greeter.java
c:\abcd> javac efgh\Blah.java
编译指定输出根,并将其第二次放在类路径上:
c:\abcd> javac -d ..\bin Greeter.java
c:\abcd> javac -d ..\bin -cp ..\bin Blah.java
两个!
c:\abcd> javac -d bin efhj\Greeter.java
c:\abcd> javac -d bin -cp bin efgh\Blah.java
至于哪个comb.java
编译 - 它与其他类没有任何依赖关系,因此编译器不需要尝试查找efgh.Greeter
或efgh.Blah
。它仅在Blah
失败,因为它找不到efgh.Greeter
。