Java 不会自动包含类

标签 java

这似乎是一个简单的问题,但不知何故我在使用这段代码时遇到了问题。几年后我又回到了 Java,并且正在制作 2D 游戏。其中,我有一个名为 SnakeGame 的主驱动程序类。加载类 GameBoard 的新实例.

贪吃蛇游戏.java

package snake2;
import javax.swing.JFrame;

public class SnakeGame extends JFrame {

public SnakeGame() {
    add(new GameBoard());

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(320, 340);
    setLocationRelativeTo(null);
    setTitle("Snake Game");

    setResizable(false);
    setVisible(true);
}

public static void main(String[] args) {
    new SnakeGame();
}
}

同一目录中有 GameBoard.java,它有一个没有必需参数的构造函数:

public GameBoard() {
    [... more code ...]
}

编辑

两者GameBoard.javaSnakeGame.javapackage snake2;在他们文件的第一行。

但是,我不断收到以下错误:

SnakeGame.java:7: cannot find symbol
symbol  : class GameBoard
location: class snake2.SnakeGame
    add(new GameBoard());
            ^
1 error

编辑 #2

我尝试使用 java -cp . GameBoard 将其添加到我的类路径中之后javac 。这是终端看起来可怕且不必要的冗长响应的第一行:

Exception in thread "main" java.lang.NoClassDefFoundError: GameBoard (wrong name: snake2/GameBoard)

这就好像我拼错了类,或者拼错了文件名。尽管据我所知,我也没有这样做过。我的代码是否还有其他我没有注意到的问题?

感谢您提前提供的任何帮助。

最佳答案

除了在同一目录中之外,GameBoard.java 中是否有 package 语句?


编辑运行程序--

@Stephen: I'm running java, and all the files are in the same directory.

来自@kbolino

You must put your source files in a snake2 directory and run javac from the parent directory [...]

您还必须使用正确的包和类路径调用 java,而不仅仅是 javac。

创建 SnakeGame 和 GameBoard stub 后对我有用的示例:

  1. 当前目录是 projects,它是 snake2 目录的父目录,其中的文件如下: java Snake2.SnakeGame

  2. 当前目录是 snake2 我正在其中编辑文件: java -cp ..snake2.SnakeGame

对于情况#2,由于您位于包目录中,因此必须将父目录放入类路径中。

.

添加了大量的信息,显示我使用 javac 编译命令和 java 运行进行的 session 。您不需要像某些人建议的那样使用 -cp 进行编译。


[~/tests/java/snake2]$ pwd
/home/stephenp/tests/java/snake2

[~/tests/java/snake2]$ cat GameBoard.java

package snake2;

class GameBoard {

    private static int instanceCount = 0;

    GameBoard() {
        GameBoard.instanceCount++;
    }

    void howMany() {
        System.out.println(instanceCount + " GameBoards have been created.");
    }
}

[~/tests/java/snake2]$ cat SnakeGame.java

package snake2;

public class SnakeGame {

    private GameBoard board = null;

    public SnakeGame() {
        this.board = new GameBoard();
    }

    void report(String msg) {
        System.out.println(msg);
    }

    public static void main(String[] args) {
        SnakeGame game = new SnakeGame();
        game.report("I exist");
        game.board.howMany();
    }
}


[~/tests/java/snake2]$ ls -1
GameBoard.java
SnakeGame.java

[~/tests/java/snake2]$ javac *.java

[~/tests/java/snake2]$ ls -1
GameBoard.class
GameBoard.java
SnakeGame.class
SnakeGame.java

[~/tests/java/snake2]$ java SnakeGame
Exception in thread "main" java.lang.NoClassDefFoundError: SnakeGame (wrong name: snake2/SnakeGame)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)

[~/tests/java/snake2]$ java snake2.SnakeGame
Exception in thread "main" java.lang.NoClassDefFoundError: snake2/SnakeGame
Caused by: java.lang.ClassNotFoundException: snake2.SnakeGame
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)

[~/tests/java/snake2]$ java -cp .. snake2.SnakeGame
I exist
1 GameBoards have been created.

包装

将您的应用程序与指定要运行的主类的 list 一起打包在 .jar 文件中,然后您只需使用即可运行您的程序

java -jar myprogram.jar

为此,请在包目录上方的目录中创建一个文件 Manifest.txt

[~/tests/java/snake2]$ cd ..

[~/tests/java]$ ls -1F
Manifest.txt
snake2/

[~/tests/java]$ cat Manifest.txt
Main-Class: snake2.SnakeGame

[~/tests/java]$ jar cfm myprogram.jar Manifest.txt snake2/*.class

[~/tests/java]$ jar tf myprogram.jar
META-INF/
META-INF/MANIFEST.MF
snake2/GameBoard.class
snake2/SnakeGame.class

您还可以围绕它包装一个脚本(shell 脚本、批处理文件等),这样您只需运行 myprogram,它就会运行 java -jar myprogram.jar

这将成为您构建过程的一部分。

关于Java 不会自动包含类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7031360/

相关文章:

java - 在 Selenium WebDriver 中执行 InternetExplorerDriver 时发生 NoSuchElementException

java - 是否有理由使用常量而不是消息?

java - 为什么 java.io.URL 去掉最后一个文件夹?

java - 适用于 IoT 的 AWS Lambda

java - 使用 Java 正则表达式提取键值对

java - 无法从 HTML 字符串格式读取 Src 属性

java - Atom 到 RSS 提要

java - 返回已完成和待处理任务的计数

java - 如何使用点表示法删除嵌套映射中的嵌套条目

java - JFreeChart : How to create a middle panel with an oscillator