两个文件Doll.java和App.java放在D盘根目录下,原代码如下: 
Doll.java 
-------------- 
package   com.abc.doll; 
public   class   Doll 

  public   void   speak() 

System.out.println("Hello"); 

}; 
App.java 
--------------- 
import   com.abc.doll.*; class   App   

public   static   void   main(String[]   args)   

Doll   d=new   Doll(); 
d.speak(); 

} d:\> javac   -d   .   Doll.java   通过 
d:\> javac   App.java     出错,错误提示如下: 
App.java:   9:   cannot   resolve   symbol 
symbol:   constructor   Doll() 
location:   class   Doll 
                                Doll   d=new   Doll(); 我后来又在App.java件头加了一句:   package   com.abc.app   编译通过并运行。 
这是为什么呢,希望各位知道的可以回答,谢谢! 
 
 
 

解决方案 »

  1.   

    问题补充:
    我后来在App.java中去掉import语句,使用com.abc.doll.Doll d=new com.abc.doll.Doll()又编译成功了,这到底是怎么一回事?
      

  2.   

    编译后的.class文件会根据你的包名存放,不同的class文件会放在不同的地方,那么在运行的时候,如果你没有导入前一个程序编译后的.class文件后,JVM会在默认的路径下寻找前一个类编译后的class文件,这样肯定是找不到的,所以要import ,后者是指定了路径下的类。
      

  3.   

    给你看篇文章你就会明白的.问题
    首先新建一个目录存放Java源文件,或者直接在某个盘符下放置程序,例如:D:\,然后按照下面的步骤进行实验(本实验在D:\目录下操作)。Step1:编写程序World.java,代码如下:package a; public class World {    public  World()    {    System.out.println(", World!");      }}Step2:编写Hello.java,代码如下:import a.World; public class Hello{    public static void main(String[] args)    {        System.out.print("Hello");        World world = new World();    }}Step3:将两个程序保存到你所建的目录下,在这里,我们将它们保存到D:\下。Step4:编译这两个Java源文件       先编译World.java,执行javac -d . World.java,在D盘生成目录a,及其中的World.class。接下来编译Hello.java,执行javac Hello.java,在D盘上生成Hello.class。Step5:运行Hello类       执行java Hello,输出Hello, World!目前一切正常。Step6:修改Hello.java将第1行的语句“import a.World;”改为“import a.*;”,重新编译Hello.java,出现下面的错误提示:错误的类文件: .\World.java文件不包含类 World请删除该文件或确保该文件位于正确的类路径子目录中。        World world = new World();        ^Step7:根据错误提示进行下列操作按照错误提示,删除 World.java 或者将 World.java 放到其他地方,则程序成功编译运行。问题:请问为何会出现Step6中的错误呢?使用 “import a.*;”导入a下所有类和接口,和使用“import a.World;”导入a包中具体的类,为何会产生上述的差异呢?回答
    当你导入一个包中所有的类时,javac在编译时并不确定你要使用的World类是a包中的类,还是其他包中的类,它会根据你机器上的CLASSPATH环境变量的值去查找类,通常我们在CLASSPATH中会设置一个点(.),表示当前目录,如果没有CLASSPATH环境变量,那么在JDK1.4之后,默认也是查找当前目录。javac在按照文件名(不包括后缀)来查找类,于是找到World.java,而这个文件根本不是字节码文件,当然就报错了。当你导入一个具体的类时,javac在分析源文件时就知道了你程序中用的类是a.World,那么它就在CLASSPATH环境变量下查找a目录下的World类,正好有,于是正确执行。为了帮助读者对这个问题加深理解,我给大家设计了下面的操作步骤(本文是在D盘上操作):(1)将a目录剪切到C:\下;
    (2)再次执行javac Hello.java,你会看到同样的错误。也就是证实了在出错之前,javac还没有去查找a包中的类(对于包是否存在的验证已经进行)。
    (3)执行set classpath=c:\。由于你明确地设置了CLASSPATH环境变量的值,并且没有包含点(.),因此javac不会再查找当前的目录。
    (4)再次执行javac Hello.java,你会发现成功执行。这里面还有一个有趣的现象,如果我们将a目录下的World.class删除,替换为World.java,那么在编译Hello.java时,World也会被自动编译。
      

  4.   

    两个文件Doll.java和App.java放在D盘根目录下,原代码如下:   
    Doll.java   
    --------------   
    package       com.abc.doll;   ??
    Doll.java 需要放在d:\com\abc\doll 下面才可以
      

  5.   

    谢谢楼主cursor_wang的精彩解答。我在这再添两句。我在sep6后,将World.java文件中 public Word() 改为 public Worlds()后, 执行 javac Hello.java
    提示如下:.\World.java:9: invalid method declaration; return type required
            public     Worlds()
                       ^
    Hello.java:16: cannot access World
    bad class file: .\World.java
    file does not contain class World
    Please remove or make sure it appears in the correct subdirectory of the classpa
    th.
                    World   world   =   new   World();
                    ^
    2 errors从第一个error 可说明: 我们在编译Hello.java 文件的时候,java VM 确实是访问了 World.java 文件。这其间的原理又该怎么解释呢?还请各位大虾能详细解释一下。thank you