Java не может найти основной класс - программирование
Подтвердить что ты не робот

Java не может найти основной класс

Я написал следующий исходный файл Java (Hello.java):

package com;

public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello!");
    }
}

Я сохраняю это на C:/tmpjava/Hello.java.

В командной строке я перехожу к этому каталогу и запускаю javac Hello.java. Затем я запустил dir:

  • Hello.class
  • Hello.java

Затем из той же директории, из которой я только запускал javac, я запускаю java Hello.class и получаю:

Exception in thread "main" java.lang.NoClassDefFoundError: Hello/class
Caused by: java.lang.ClassNotFoundException: Hello.class
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Could not find the main class: Hello.class.  Program will exit.

Что здесь происходит?!? Как javac работает нормально, но не java?

4b9b3361

Ответ 1

Ваш класс Hello принадлежит к пакету com. Таким образом, полное имя вашего класса com.Hello. Когда вы вызываете программу с использованием java в командной строке, вы должны указать полное имя класса, содержащее ваш метод main, и опустить класс. Например:

java com.Hello

Программа Java нуждается в этом полностью квалифицированном имени класса, чтобы понять, к какому классу вы обращаетесь.

Но у вас есть еще одна проблема. Программа java находит пакеты, подпакеты и классы, принадлежащие им, используя файловую систему. Поэтому, если у вас есть структура пакета, такая как com.Hello, программа java ожидает найти файл класса с именем Hello.class в каталоге с именем com, например: com/Hello.class. Фактически вы можете наблюдать это поведение в Exception, которое вы видите; вы неправильно использовали Hello.class, который java интерпретирует как пакет с именем Hello, и класс с именем class, и ищет структуру каталогов Hello/class:

java.lang.NoClassDefFoundError: Hello/class

Но компилятор javac не поддерживает эту структуру каталогов по умолчанию. См. Документацию для javac, но важный бит таков: когда вы делаете свои компиляции, вы можете указать целевой каталог с помощью -d флаг:

-d каталог

Установите целевой каталог для файлов классов. Целевой каталог должен уже существовать; javac не будет создавать целевой каталог. Если класс является частью пакета, javac помещает файл класса в подкаталог, отражающий имя пакета, при необходимости создавая каталоги. Например, если вы указываете -d c:\myclasses и класс называется com.mypackage.MyClass, тогда файл класса называется c:\myclasses\com\mypackage\MyClass.class.

Если -d не указано, javac помещает файл класса в тот же каталог, что и исходный файл.

Последний бит, выделенный жирным шрифтом, является источником большой путаницы для новичков и является частью вашей собственной проблемы.

Итак, у вас есть две альтернативы:

  • В вашем случае это нормально, если вы укажете текущий каталог как целевой каталог, например (период . означает текущий каталог):

    javac -d . Hello.java
    

    Если вы вызовете такой компилятор, он создаст для вас каталог com и поместит в него файл скомпилированного класса, способ, которым Java-программа ожидает его найти. Затем, когда вы запускаете java, как указано выше, из c:\tmpJava, ваша программа должна выполнить.

  • Вы можете настроить исходный код, используя структуру каталогов, которая отражает структуру вашего пакета: поместите свой исходный файл Hello.java внутри каталога com, в вашем случае: c:\tmpJava\com\Hello.java, Теперь из c:\tmpJava вы можете выполнить компиляцию javac следующим образом:

    javac com\Hello.java
    

    Вы не указали флаг -d, но это прекрасно, потому что вы сами создали структуру каталогов и снова цитировали приведенную выше документа:

    Если -d не указано, javac помещает файл класса в тот же каталог, что и исходный файл.

    Опять же, когда вы запускаете java, как указано выше, ваша программа должна выполнить.

    Обратите внимание, что этот второй вариант - это тот, который обычно используется java-программистами: файлы исходного кода организованы в структуре каталогов, которая отражает структуру пакета.

В этом объяснении мы проигнорировали концепцию classpath. Вам также нужно будет понять, что для написания java-программ, но в вашем случае просто компиляция программы в текущем каталоге - если вы следуете одной из двух альтернатив выше при компиляции своего класса, вы можете уйти, не задав путь к классам, потому что, по умолчанию программа java имеет текущий каталог как путь к классам. Другая цитата из этой статьи документация для java:

-cp classpath

Укажите список каталогов, архивов JAR и ZIP-архивов для поиска файлов классов. Записи пути пути разделяются точкой с запятой (;). Задание -classpath или -cp переопределяет любой параметр переменной среды CLASSPATH.

Если -classpath и -cp не используются, а CLASSPATH не установлен, путь к пользовательскому классу состоит из текущего каталога (.).

Обратите внимание, что когда вы используете IDE, например Eclipse, для запуска вашего java-кода, это в основном используется для вас, но вы все равно столкнетесь с проблемами класса.

Ответ 2

Синтаксис команды Java:

java [classname]

не

java [filename]

Java ищет в своем классе путь к классу имени, которое вы предоставили. Обычно classpath включает текущий каталог, поэтому:

java Hello

... найдет Hello.class в текущем каталоге и запустит его метод main().

Однако, если класс находится где-то в другом месте (например, в .jar или где-то еще в файловой системе), вы можете указать его с помощью переменной среды CLASSPATH или в командной строке:

java -cp build/classes Hello
java -cp build/jars/myjar.jar Hello

Ответ 3

Класс должен находиться в C:\tmpjava\com\Hello.class
И вы должны бежать от C:\tmpjava: java -cp . com.Hello
Когда вы кладете класс в пакет, он определяет файловую структуру класса. То есть ваш класс, который в пакете com должен находиться в папке com

Ответ 4

Выполните следующую команду

java -cp . com.Hello

Ответ 5

java -classpath c:\tmpjava com.Hello