今天在使用命令行编译时遇到些问题,顺便又仔细分析了一些基础知识,记录总结一下。

下面使用javac和java命令都是在 D:\Workspace\java目录下执行的:

 1 //Inner.java
2 package cn.inner;
3 public class Inner
4 {
5 public static void show()
6 {
7 System.out.println("I'am inner class.");
8 }
9 }
10
11 //DoTest.java
12 import cn.inner.*;
13 public class DoTest
14 {
15 public static void main(String[] args)
16 {
17 Inner.show();
18 }
19 }

javac -d . Inner.java

javac DoTest.java

折腾半天,最终把 Inner.java 删掉、重命名都能够使 DoTest.java 编译成功。

自己思索半天,想到一个合理的解释: javac  命令在编译源文件时,如果源文件中有对其他类的调用(例如本例中的 Inner 类的调用),

它首先会在与源文件相同的目录下(即是与该类相同的包下)寻找是否有该类存在,在示例中发现了 Inner.java 源文件存在(该源文件中肯定存在一个 Inner 类),

但是事实上 Inner.java 是属于 cn.inner 包下的类,即 cn.inner.Inner 。 检查到这里, javac 命令就报错了,提示错误的源文件 ...

为了进一步证实我的假设,我修改 DoTest.java 文件,增加了默认包名:

package src;

在当前目录下执行:

Javac -d . DoTest.java

成功!

这时在分析下 DoTest.java 原源文件中导入的其它类:

由于该源文件中有导入 cn.inner.Inner 类,在使用 javac 命令编译时,该命令会按照 classpath 环境变量的路径去搜索导入的类,我的环境变量中有配置 "." ,

所以在当前目录下可以正确寻找到 cn.inner.Inner 类, 在当前目录下执行 javac DoTest.java  命令成功

但是在执行 java DoTest  命令时,出现下面的结果

这时才发现原来 DoTest.java 中增加了包名的限制,所以需要把 DoTest.class  文件移到 src 目录下,或者编译时加上 "-d ." 参数,即 javac -d . DoTest.java  命令

再执行 java src/DoTest  成功

总结: java 中包名的层级关系是用目录来体现的,比如 cn.inner 包就对应 cn\inner 这两层目录,在编译代码的过程中,如果有 import 其他包中的类,

则使用 javac 命令的命令行窗口的目录必须可以按照 classpath 环境变量的路径搜索到 import 进来的类。另外值得一提的是,编译后的类都应该按照包名规定放在指定目录下,

还需要注意被引入的类的源文件和使用引入类的源文件不能放在一起,除非两个文件都是默认包,如果是这种情况也不会使用 import 引入另外一个类了。

当然,我今天提到的这些问题,在 IDE 开发中一般都不会遇到,只是觉得这样能够更加深刻的理解 java 的一些基础问题。

最新文章

  1. wpf 异常处理和关闭进程
  2. 调用KEditor批量上传图片
  3. Atititi 版本管理 rc final rtm ga release 软件的生命周期中一般分4个版本
  4. JavaScript闭包学习笔记
  5. Python2
  6. 算法----序列和的 top N
  7. codeforces #232 div2 解题报告
  8. java_java 利用JAX-RS快速开发RESTful 服务
  9. ios9新特性概述
  10. Spring中bean的scope
  11. 11g 创建asm磁盘组
  12. visul svn+花生壳
  13. i++与++i的区别,使用实例说明
  14. 快速构建Windows 8风格应用19-基础控件II
  15. MongoDB分组
  16. Android4.0Sd卡移植之使用vold自动挂载sd卡
  17. 优化之Normalizer组件
  18. java http 请求的工具类
  19. [转] An Introduction to Mutual SSL Authentication
  20. mysql 查看正在执行的语句

热门文章

  1. HDU - 6103 :Kirinriki(不错的尺取法)
  2. django国际化总结
  3. C# 实现程序只启动一次(总结)
  4. 关于Apache Phoenix和Cloudera结合
  5. Windows下通过Composer安装Yii2 [ 2.0 版本 ]
  6. android jUnit test 进行自动化测试
  7. laravel中好用的支付安装包
  8. Oracle 数据库备份还原(Expdp/impdp)记录
  9. Difference between boot ip. service ip and persistent ip in hacmp
  10. java从键盘输入打印出直角三角形