这个是一道SCJP的模拟题:
给出类定义: package com.company.application; public class MainClass {
 public static void main(String[] args) { }
 }已知该类编译好的MainClass.class文件被放在/apps/com/company/application下,而且知道系统环境CLASSPATH变量设置为“.”,那么由答案:
在/apps/com/company/application目录下运行java -classpath . MainClass,jvm会无法找到MainClass类。
我试验了一下,确实找不到,不过不明白为什么,-classpath .不是提供了当前目录为相对的路径,既然MainClass.class在当前目录下,为什么JVM找不到呢?
而且我还试验了一下,直接java MainClass居然也说找不到MainClass类。
希望高手指教究竟问题出在哪里。 

解决方案 »

  1.   

    因为MainClass的包是com.company.application
    所以他的编译后的路径是com/company/application/MainClass
    而你不能在class的编译路径中运行class, 也就是至少在com上一级的目录下运行. 这里就是apps/
      

  2.   

    我发图,参考下:1.jdk安装路径:C:\Program Files\Java\jdk1.6.0_10\
    2.配置环境变量:path=.;C:\Program Files\Java\jdk1.6.0_10\bin;C:\Program Files\Java\jdk1.6.0_10\lib   
    3.用cmd测试:  运行cmd,直接在命令提示符后输入javac  如:C:\Documents and Settings\Administrator>javac   
      效果如下        C:\Documents and Settings\Administrator>javac
           用法:javac <选项> <源文件>
           其中,可能的选项包括:
            -g                         生成所有调试信息
            -g:none                    不生成任何调试信息
            -g:{lines,vars,source}     只生成某些调试信息
            -nowarn                    不生成任何警告
            -verbose                   输出有关编译器正在执行的操作的消息
            -deprecation               输出使用已过时的 API 的源位置
            -classpath <路径>            指定查找用户类文件和注释处理程序的位置
            -cp <路径>                   指定查找用户类文件和注释处理程序的位置
            -sourcepath <路径>           指定查找输入源文件的位置
            -bootclasspath <路径>        覆盖引导类文件的位置
            -extdirs <目录>              覆盖安装的扩展目录的位置
            -endorseddirs <目录>         覆盖签名的标准路径的位置
            -proc:{none,only}          控制是否执行注释处理和/或编译。
            -processor <class1>[,<class2>,<class3>...]要运行的注释处理程序的名
          的搜索进程
            -processorpath <路径>        指定查找注释处理程序的位置
            -d <目录>                    指定存放生成的类文件的位置
            -s <目录>                    指定存放生成的源文件的位置
            -implicit:{none,class}     指定是否为隐式引用文件生成类文件
            -encoding <编码>             指定源文件使用的字符编码
            -source <版本>               提供与指定版本的源兼容性
            -target <版本>               生成特定 VM 版本的类文件
            -version                   版本信息
            -help                      输出标准选项的提要
            -Akey[=value]              传递给注释处理程序的选项
            -X                         输出非标准选项的提要
            -J<标志>                     直接将 <标志> 传递给运行时系统
          C:\Documents and Settings\Administrator>这说明配置的环境变量可用,就是说在任何路径下面可以直接编译java文件
      

  3.   

    你可以到任意路径下面,输入javac 效果应该是一样的!!
      

  4.   

    楼主在/apps下运行
    java  com.company.application.MainClass 试试
      

  5.   

    set classpath 看看classpath是否包含D:/apps(假定你在D盘)
      

  6.   

    看错题目了 呵呵``   LZ是不是想了解-classpath的用法啊        -classpath是当你要编译或执行的类引用了其它的类,但被引用类的.class文件不在当前目录下时,就需要通过-classpath来引入类  
      

  7.   

    好吧,我把所有的选项都贴出来:
    题目如我在问题中的描述,
    A. 在/apps目录下执行java MainClassrectory
    B. 在/apps目录下执行java com.company.application.MainClass
    C. 在任意目录下执行java -classpath /apps com.company.application.MainClass 
    D. 在/apps/com/company/application目录下执行java -classpath . MainClass (这个也正好是我的提问)
    E. 在/apps目录下执行 java -classpath /apps/com/company/application:. MainClass 
    F. 在/apps/com/company/application目录下执行java com.company.application.MainClass给出的正确答案是BC
    B明显是可以的,C根据-classpath的绝对路径,也是可以的。(所以说并不存在只能在/apps级别的目录才能访问MainClass的说法,C的情况我是亲自编译试验过的。)
    关于D我现在都没有看到合理的解释。
      

  8.   

    回楼上,无论你在哪里运行这个Main.class你都是要输入它的完整包名加类名的。
    通过SCJP的路过~~~~~~~
      

  9.   

    包结构和文件结构是对应的
    执行java com.company.application.MainClass,它会在当前目录下找com/company/application/MainClass.class
    显然这样是找不到的啊 
      

  10.   

    也就是说,如果我要用相对目录定位的话,那么我的-classpath参数需要定位到 ../apps, 然后jvm会根据class中的package自动在往下找com/mycomany/application;如果我的当前目录已经在apps/com/以下或更深层次的地方,那我就不能应用当前目录作为相对目录,而应当引用-classpath /apps com.mycompany.application.MyClass 来寻找类,是这个意思吗?
      

  11.   

    对,就是这个意思。如果在系统变量classpath里找不到,那么你必须手动添加参数。
      

  12.   

    好的!现在问题搞清楚了,总结如下:
    1. java类的路径定位由两部分组成:package所定义的路径com/company/application以及-classpath所指定的路径。两者综合起来必须准确地定位到类所在的目录。
    2. package所定义的路径是jvm无论如何都要依照顺序查找的,因此如果用户所在的目录在com.company/application以外(比如说当前目录为/apps),则需要在-classpath中加入/apps参数,这样配合package定义的com/company/application才能定位到类。
    3. 如果用户所在的当前目录本身已经在/com/company/application的某一级当中,那么这时-classpath参数就不能再从当前路径查找,而是应当采用绝对路径,从根目录开始查找。例如当前目录在c:\apps\com\company\application下,MainClass.class也在该目录下,那么使用java -cp /apps com.company.application.MainClass就可以运行类。(我再次声明在class的编译路径中是可以运行类的,我都说C我试验过了,怎么还有人在那里瞎顶???)感谢bruni的解释,虽然不全面,但是编译路径的概念给了我提示。
    彻底感谢tince的解释,他让我完全整明白了。