与Java包混淆

时间:2014-09-07 14:02:32

标签: java class static packages final

所以我认为我理解了包装,但事实证明我没有。

  • 包内的类:我有这个文件夹结构:mypackage/mysubpackage。在mysubpackage文件夹里面我有两个类:

    package mypackage.mysubpackage;
    
    public class Class1 {...}
    

    package mypackage.mysubpackage;

    public class Class2 {...}

但是,当我在目录javac Class1.java内使用mypackage/mysubpackage编译Class1(使用Class2中的方法)时,它无法看到Class2:

Class1.java: error: cannot find symbol
    Class2 c = new Class2();
    ^
symbol:   class Class2
location: class Class1

如果我在包含javac Class1.java的目录中运行mypackage/mysubpackage,它可以正常工作。不应该在mysubpackage文件夹里面编译工作吗?

  • 另一个包中的类:现在,我有另一个类,我希望可以访问所有子包的方法,所以我在{{{{}}内创建了一个Commons.java 1}}:

    mypackage/commons

然后我更新Class2导入该类,以便我可以在类中使用它的方法:

package mypackage.commons;

public final class Commons {

    public static double method() {...}
    ...
}

现在它找不到我在最终类中定义的方法:

    package mypackage.mysubpackage;

    import mypackage.commons.*;

    public class Class2 {...}

如果找不到它?我想我正确地导入它,方法是静态的,类是最终的。为什么不识别呢?

干杯!

4 个答案:

答案 0 :(得分:2)

从命令行启动Java编译器时,您的问题在于设置工作目录。

我建议你选择一个集成开发环境 - Eclipse is a good one。使用IDE,您不会遇到此类问题。以下是我刚刚在Eclipse中创建的类,它们编译了correclty。

<强>共享

package com.example.packagecommons;

public class Commons {

     public static double method() {
        return 0;}
}

<强>的Class1

package com.example.packages;

public class Class1 {
    private Class2 c2;
    public Class1() {
        c2 = new Class2();
    }
}

<强>的Class2

package com.example.packages;

import com.example.packagecommons.Commons;
public class Class2 {
    private double initialValue;
    public Class2() {
        initialValue = Commons.method();
    }
    public double getValue() {
        return initialValue;
    }
}

答案 1 :(得分:2)

假设您的两个类Demo01和Demo03在包pack1.subpack中,而您的Demo02在pack2

所以层次结构就像

  • someDrive / PACK1 /子套件/ Demo01
  • someDrive / PACK1 /子套件/ Demo03
  • someDrive / PACK2 / Demo02
  • someDrive / PACK1 /普通/ Demo04

其中Demo01是

package pack1.subpack;
import pack2.Demo02; // need to add this if calling class of different package
import pack1.common.Demo04; // if you are going to use Demo04 class in Demo01 class
public class Demo01 {

public void run() {
    System.out.println("--running Demo01-");
}
public static void main(String[] args){
    Demo01 demo01 = new Demo01();
    demo01.run();
    Demo02 demo02 = new Demo02();
    demo02.run();
    Demo03 demo03 = new Demo03();
    demo03.run();
    Demo04.run();
 }
}

Demo02是

package pack2;
public class Demo02 {

public void run() {
    System.out.println("--running Demo02--");
}
}

Demo03是

package pack1.subpack;   
public class Demo03 {

public void run() {
    System.out.println("--running Demo03--");
}
}

Demo04是

package pack1.common;

public final class Demo04 {

public void run() {
    System.out.println("--running Demo04--");
}
}

然后使用javac pack1/subpack/Demo01.java

编译它

并使用java pack1/subpack.Demo01

执行它

答案 2 :(得分:2)

我知道这个帖子已经老了,但我想澄清一些事情,以便帮助未来的观众。

您的第一个问题基本上是,Java运行时系统如何知道在哪里查找您创建的软件包?记住这3条规则(其中一条必须适用):

  1. 您的主程序包必须位于当前工作目录的子目录中才能找到。
  2. 您可以通过设置CLASSPATH环境变量来指定目录路径。
  3. 您可以使用-classpath选项与javajavac来指定通过终端/ cmd执行代码时类的路径。
  4. 要回答您的第一个问题,您正在执行mypackage/mysubpackage的代码。要使Java运行时识别Class2,您必须从mypackage执行。

    回到第二个问题,当你使用*导入包的所有内容时,需要通过在它们之前显式编写类名来引用静态类成员,因为Java不知道哪个类在你指的包裹。因此,在您的代码中,您必须编写 Commons.method()而非method()。如果您不想一次又一次地为类的名称添加前缀,则可以显式导入所需的特定类。在您的情况下,这将是mypackage.commons.Commons。然后你可以直接调用method()(前提是它是静态的)。

答案 3 :(得分:0)

sh$ cd package/subpackage
sh$ javac Class1.java

将导致错误,因为编译器将尝试在当前目录的Class2子目录中找到package/subpackage

你必须以这种方式编译:

sh$ javac package/subpackage/Class1.java

这是一个完整的工作示例:

sh$ cat pkg/subpackage/Class1.java
package pkg.subpackage;

import pkg.commons.Class2;

public class Class1 {
    public static void main(String args[]) {
        Class2.doSomething();
    }
}

sh$ cat pkg/commons/Class2.java 
package pkg.commons;

public class Class2 {
    public static void doSomething() {
        System.out.println("hello");
    }
}

sh$ javac pkg/subpackage/Class1.java
sh$ java pkg.subpackage.Class1
hello