Java:windows shell 下package和import的问题:类放在同一包下为什么显示cant find symbol?

使用cmd或者powershell运行java注意事项

不使用IDE时,我们编写多个java文件后想要编译并测试运行的话,需要注意一些问题
对于运行入口的App.java或者测试XXTest.java而言,需要cmd在根package目录的上一级目录下运行
比如你要写一个软件,myapp,创建了根目录myapp,编写的所有类文件都在myapp内
软件入口App.java位于 myworkspace\myapp\App.java
在保证myapp下所有类的import和package以myapp为根命名时
编译此文件,cmd的访问位置必须是:myworkspace > javac myapp/App.java

cmd访问方式产生的问题

如果在App.java当前或者其他目录按相对路径访问java文件,比如

myworkspace\myapp> javac App.java 
F:> javac myworkspace\myapp\App.java

问题:

如果App.java有非同文件下的依赖类:
编译器报cant find symbol 错误

原因:

是cmd下编译java文件,当前类需要某个外部依赖类字节码时,
1. 写了package没写import
编译器读取package标识,按照其路径,在cmd位置,向下扫描依赖类
1-1. 如果找到依赖类,访问class文件,读取package标识,标识为同包即找到该依赖类 OK!
1-2. 如果找到依赖类,访问class文件,读取package标识,标识为不同包即未找到
如果2)始终找不到package标识相同的依赖类class文件,显示错误,cant find symbol,bad class file

2. 写了import,或标识了类前缀
如果1中过程没找到依赖类,编译器就读取import标识和前缀,按照其路径,在cmd位置,向下扫描依赖类,
后面具体过程和1-11-2相同

显然,按照java规范,cmd如果不在根package上一级目录,运行编译,那么肯定找不到依赖类(import配置过环境变量的java classpath除外),相反就是package与import命名不规范。

举个不同包(2个类package命名不同,或不在一个物理地址目录下)的例子

情景
假设我们有2个java文件 App.java(未编译) Dependency.java(已编译),App继承Dependency,或调用其静态字段和方法
设package根目录为\app 物理地址c: \home\app
Dependency目录: \app\dependency 即Dependency.java注明 package app.dependency;
App目录: \app 即App.java注明 package app; import app.dependency.Dependency;

此时假设cmd在\app运行
c:\home\app > javac App.java
显示错误: cant find symbol;描述原因:package app.app.dependency不存在;按照import app.dependency.*找不到Dependency.class;

过程描述:编译器读取了App.java,先按照App所在包package app; ;以c:\home\app为当前位置,向下查找\app文件夹看是否有Dependency.class,发现c:\home\app\app不存在。
然后启动import,按照import app.dependency.Dependency; ,查找c:\home\app\app\dependency\Dependency.class,发现不存在

解决方法:cmd在package根目录上一级运行编译即可。

注意这里有个trick,类的package命名同包,但是物理地址不在一个目录下,虽然实际上类不同包,但可以不用import访问依赖类,如下:

设package根目录为\app 物理地址c: \home\app
Dependency目录: \app\dependency Dependency.java注明 package app.dependency; 违反规范!
App目录: \app 即App.java注明 package app.dependency;
此时假设cmd在app上一级目录运行javac编译App.java,
App可以访问Dependency的公开字段和方法,且不用写import
但是对于保护字段和方法就不行,系统会显示Exception in main thread trying to access protected field,即使是“同名的包”

猜你喜欢

转载自blog.csdn.net/OliverZang/article/details/84832589