Статический блок не выполняется в JDK 7, "Основной метод не найден", но работает в JDK 1.5
Я написал простой класс с одним статическим блоком
class Hello
{
static {
System.out.println("Hello");
System.exit(0);
}
}
Когда я запускаю его с помощью jdk1.5, статический блок запускается
C:\apps\Java\jdk1.5.0_21\bin>javac Hello.java
C:\apps\Java\jdk1.5.0_21\bin>
C:\apps\Java\jdk1.5.0_21\bin>
C:\apps\Java\jdk1.5.0_21\bin>
C:\apps\Java\jdk1.5.0_21\bin>java Hello
Hello
Но когда я запускаю его с помощью jdk1.7, я получаю следующую ошибку
C:\Program Files (x86)\Java\jdk1.7.0_02\bin>
C:\Program Files (x86)\Java\jdk1.7.0_02\bin>javac Hello.java
C:\Program Files (x86)\Java\jdk1.7.0_02\bin>java Hello
Error: Main method not found in class Hello, please define the main method as:
public static void main(String[] args)
Кто-нибудь может подумать об этом изменении поведения в JDK 5 и JDK 7?
Спасибо заранее!
Ответы
Ответ 1
Java 7 ищет основной метод перед загрузкой класса. Это изменение поведения от предыдущих java-версий и, следовательно, ваш статический блок не выполняется. В предыдущих версиях поведение состояло в том, что JRE использовал поиск основного метода после загрузки класса и после выполнения статических блоков.
Ответ 2
Да, в jdk7. Статические блоки сначала не выполняются. Сначала он выглядит для точки входа в приложение.
Итак, сначала он проверяет public static void main(String a[])
, если этот метод отсутствует, статический блок не будет выполнен.
Ответ 3
Пройдите JLS 12.1:
Виртуальная машина Java начинает выполнение, вызывая основной метод метода определенного класса, передавая ему единственный аргумент, который представляет собой массив строк. В примерах в этой спецификации этот первый класс обычно называется Test.
Первоначальная попытка выполнить метод main класса Test обнаруживает, что класс Test не загружен - то есть, что виртуальная машина Java в настоящее время не содержит двоичное представление для этого класса. Виртуальная машина Java затем использует загрузчик классов, чтобы попытаться найти такое двоичное представление.
Java 7 ищет метод public static main(String[] args)
, который является точкой входа для приложения, а затем загружает класс, в отличие от Java 6, который загружает класс, а затем ищет метод main
.
Ответ 4
Вероятно, вам нужно применить метод public static void main(String[] args){ }
в вашем классе для JDK7.
В JDK7 основное присутствие метода проверяется перед статическим блоком, и если он не находит его, вы получаете исключение.
Ответ 5
Программа не выполняется, потому что из JDK 1.7 oracle поставлено ограничение на метод статических блоков и статических переменных, если ваша программа не имеет основного метода с правильной подписью, но статический блок и метод всегда будут выполняться первыми. Как управление памятью статических переменных выполняется во время загрузки класса.
Ответ 6
Если вы внимательно прочитали главу 12 JLS (версия 5 или 7), она не указана, когда должна произойти статическая инициализация класса "main". На самом деле есть Отчет об ошибках, который жалуется на это.
Указывается, что инициализируется "основной" класс (и будут запускаться статические инициализаторы) до вызова метода точки входа. Это указано в JLS 12.4.1
Я не могу объяснить, почему они изменили это, или найти, где они задокументировали это изменение. Но, видимо, это изменилось. Если вам нужны реальные объяснения, вам нужно будет спросить инженеров Sun/Oracle.
(FWIW, я думаю, что это хорошее изменение. Происходит статическая инициализация, а затем отказ программы из-за того, что не найти точку входа является неожиданным поведением, а неожиданное плохо, если нет хорошего оправдания.)
Ответ 7
Вы не можете выполнить java-программу без метода main, если иначе это не апплет или что-то еще. Я говорю, что ваше наблюдение на jdks может быть неправильным
Ответ 8
Upto JDK1.6: -
Сначала загружается класс, и при загрузке будет выполняться статический блок класса.
а затем проверьте основной метод выполнения.
JDK1.7 и далее:
Сначала проверяет основной метод, доступен ли он или нет.
if available
then first execute static and
then main method will be executed.
if not available
throw error