Привет, мир работает, но потом появляется ошибка, что нет основной?

У меня есть следующий простой мир привет в Java:

class A {
    static {
        System.out.println("Hello world");
    }
}

Он работает так, как ожидалось, но, как ни странно, он дает ошибку, говоря, что основной метод не существует после.

$ javac A.java && java A
Hello world
Exception in thread "main" java.lang.NoSuchMethodError: main

Почему? Должен ли я игнорировать это? Я даже попытался сделать метод "main", но ничего не меняет.

class A {
    static {
        main();
    }
    public static void main() {
        System.out.println("Hello world");
    }
}

$ javac A.java && java A
Hello world
Exception in thread "main" java.lang.NoSuchMethodError: main

Ответы

Ответ 1

Когда ваш класс загружен, будут запущены инициализаторы static, а затем JVM попытается вызвать метод main. Вы можете исправить это, добавив еще одну строку в ваш инициализатор static:

public class HelloWorld {
    static {
        System.out.println("Look ma', no hands!");
        System.exit(0);
    }
}

Это остановит JVM, прежде чем попытается вызвать ваш метод main.

Также обратите внимание, что это не будет выполняться в Java 7. Java 7 ищет метод main перед инициализацией класса.

Ответ 2

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

Код в классе, заключенном в статический блок, который находится вне любого метода, будет выполняться при первой ссылке этого статического класса.

Причина, по которой он не может найти ваш основной метод, заключается в том, что вы указали его неправильно. Main выглядит так:

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

Привыкнуть к этой строке. Вы увидите это много раз.

Аргумент String [] args... - это список аргументов, обозначенных пробелами, которые пользователь может передать вашей программе через оболочку. Все программы входят в основной метод. Это стандарт, переданный в течение некоторого времени.

Статический блок может использоваться в классе для запуска вашей программы, но это может вызвать путаницу и быть крайне неправильным. Использование основного метода в качестве точки входа является отраслевым стандартом.

Я не могу объяснить причину, по которой это стандарт, или дать более убедительный аргумент в пользу того, почему использовать его, кроме как вводить вашу программу в оболочку. Я не предлагаю запускать вашу программу из статического блока.

Ответ 3

Забудьте блок static и сделайте следующее:

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

Ответ 4

Вам нужен метод main. В последнем примере кода вы неправильно определили его. Определите это следующим образом:

public static void main(String[] args) {

}

Вам не хватало args, почему он все еще жаловался во второй раз.

@WilliamMorrison и @Jeffrey объяснили, почему ваша программа выводит "Hello world", а затем сбой.

Существует очень веская причина использовать main вместо того, как вы используете блок static. В основном, это точка входа в вашу программу. Вы не можете успешно запустить свою программу из команды java без нее. Вы не можете выполнить файл jar без него. И, как вы видели, вы будете. Если вам не хватает основного, вы будете получать эту ошибку каждый раз, если вы не напишете взломать ее (см. @Jeffrey). Я не имею в виду, что в наступлении Кстати, его ответ очень информативен, но это взлом ИМО).

Другое дело, что это не идиоматично. Если бы мне пришлось читать ваш код, мне было бы интересно: "Куда начинается этот freaking-код?!" Я не смог бы загрузить его и выяснить, как получить мои инструменты (IDE, maven, ant и т.д.), Чтобы запустить его. Intellij не знает, что он может запускать класс без метода main. Это стандартная точка входа в программу.

Случайный блок static не является точкой входа. Там нет способа передать в него аргументы. Например, если вы хотите написать программу командной строки, такую ​​как unix "cat", где вы передаете имя файла, и выводит содержимое файла, вы не могли бы сделать это с помощью блока static, потому что не было бы способа установить и получить ввод.

Ответ 5

Он работает так, как ожидалось, но странно: класс загружается. И когда класс загружен, его статические блоки выполняются.

Почему вы получаете Exception in thread "main" java.lang.NoSuchMethodError: main

Потому что в первом случае у вас нет основного метода, а во втором случае подпись неверна.

измените его на public static void main(String a[])

Ответ 6

Когда классы загружаются в JVM, он сначала "обрабатывает" то, что находится в статическом блоке, поэтому сначала печатает "Hello World", который объясняет эту часть:

class A {
    static {
        System.out.println("Hello world");
    }
}

При запуске программы он ищет "основной" метод, поэтому сначала выводит Hello World, затем ищет основной метод, поэтому ошибка, такая же логика применяется, когда вы вызываете метод внутри статического блока,