首先,我都是在控制台下编译执行的,没有用IDE。
在G:\javatest 下面有两个源文件 Ss.java Demo.java(名字没有意义,是临时乱取的)
Ss.java代码如下:
package test;   
public interface Ss{
  int a=2;
  void f( );
}
编译命令 javac -d . Ss.java 在当前目录G:\javatest下面创建包testDemo.java代码如下:
import test.*;  
public class Demo implements Ss{
  public void f(){
  System.out.println("a="+a);
  }
  public static void main(String args[]){
  Demo d=new Demo();
  d.f();   }
}
编译命令 javac Demo.java
控制台下的错误如下:
Demo.java:2: 无法访问Ss
错误的类文件: .\Ss.java
文件不包含类Ss
请删除该文件或确保该文件位于正确的类途径子目录中。
public class Demo implements Ss{
                              ^问题1:如果将红色的代码改为import test.Ss;
编译通过,
java Demo
成功执行。
这是什么原因?针对上面这个错误,下面稍作改动。
问题2:红色代码保持不变
将Ss.java放到包test里面,然后
javac -d . Ss.java
javac Demo.java
编译通过,
java Demo
成功执行。问题3:红色代码保持不变
首先javac -d . Ss.java,此时在test中生成了Ss.class,然后将Ss.java删除,
javac Demo.java
编译通过,
java Demo
成功执行问题4:红色代码保持不变在Demo.java文件中加入语句package test.inside;即在包test下创建子包inside
首先javac -d . Ss.java,
然后javac -d . Demo.java,
编译通过,
java test.inside.Demo
成功执行。
问题4我有这样的想法,不知道对不对
如果Demo.java所在的包(文件夹)在他使用的类Ss.java所在的包(文件夹)的子目录下,即:如果使用的是上一层目录里面的类,那么不需要将.java文件放入包中,import *即可编译通过。
而如果Demo.java使用的类Ss.java所在的包(文件)在他Demo.java所在的包(文件)的子目录下,即:如果使用的是子目录里面的类,那么必须要将.java文件放入包中,否则import *编译报错。

解决方案 »

  1.   

    类加载造成的,要加载一个类,就是在使用一个类的时候并且在JVM中还没有这个类的信息,import packageName.*; 这种import方式并没有使用任何的类,在遇到这样的import语句时,并没有加载packageName包下的类,import packageName.ClassName; 这种import方式使用了类名为ClassName的类,遇到import语句时就加载packageName.ClassName类了。
    LZ的代码应该是这样组织的:
      G:\javatest\Ss.java
      G:\javatest\Demo.java
      G:\javatest\test\Ss.class如果用import test.*;,在编译Demo.java的时候,在分析到implements 的时候才去加载Ss类,这个时候编译就会在CLASSPATH,在与Demo.java相同的目录下就找到了Ss.java,所以就编译Ss.java,可是和Demo.java不同包,所以编译通不过,而用import test.Ss;在编译的时候在分析import的时候就加载了而且包名、路径都正确,之后在用Ss的时候就不会在去找Ss.java了。这就是#12使用-verbose看到的情况了。
      

  2.   

    再仔细的了解JAVA类加载机制就明白了,最好是找本书看看吧
      

  3.   

    这种问题 还是路径错了你看看你建立的文件夹中有没有这个CLASS 用IDE用习惯了  一般不捣鼓这些东东了