Какие преимущества предоставляет main(...) по сравнению с использованием статического инициализатора в качестве псевдопункта входа?

StackOverflow https://stackoverflow.com/questions/1298342

Вопрос

Точка входа в программу на Java обычно выглядит примерно так


    // MyMain.java
    public class MyMain{  
      //whatever 
        public static void main(String args[]){ 
        System.out.println("balderdash");
        }
    }

Однако, поскольку в main есть только один SOP, приведенный выше класс может быть таким вместо этого


    // MyMain.java
    public class MyMain{
        //whatever
        static {    
        System.out.println("balderdash");
        }
    }

Одним из очевидных преимуществ использования main(...) является то, что аргументы могут быть переданы в программу.Другой (я предполагаю здесь) может быть связан с тем, что средство сбора мусора по-другому обрабатывает объекты, созданные в статическом блоке.

Какие еще преимущества дает использование определяемой языком точки входа - public static void main( String args[] ) вместо использования статического инициализатора.

p.s.Приведенные выше фрагменты приведены только для иллюстрации и могут быть недоступны для компиляции

Это было полезно?

Решение

  • Вы можете протестировать его или вызвать из других приложений.
  • Это то, чего будут ожидать другие люди.
  • Если вы запустите все свое приложение в контексте статического инициализатора, я подозреваемый фактически вы будете удерживать блокировку этого типа в течение всего времени.Если какой-либо другой поток попытается вызвать статический метод в том же классе, он будет заблокирован.Именно с такой проблемой вы сталкиваетесь, когда пытаетесь использовать концепцию неожиданным образом - это просто концептуально "неправильно".Инициализация класса - это просто не то же самое, что запуск приложения.

Редактировать:Вот пример этой проблемы:

class SampleTask implements Runnable
{
    public void run()
    {
        System.out.println("Calling someStaticMethod");
        Test.someStaticMethod();
        System.out.println("someStaticMethod returned");
    }
}

public class Test
{
    static
    {
        System.out.println("Starting new thread...");
        new Thread(new SampleTask()).start();
        System.out.println("Thread started. Sleeping");
        try
        {
            Thread.sleep(5000);
        }
        catch (InterruptedException e)
        {
            System.out.println("Interrupted!");
        }
        System.out.println("Finished sleeping");          
    }

    public static void someStaticMethod()
    {
        System.out.println("In someStaticMethod");
    }

    public static void main(String[] args)
    {
        System.out.println("In main. Sleeping again.");
        try
        {
            Thread.sleep(5000);
        }
        catch (InterruptedException e)
        {
            System.out.println("Interrupted!");
        }
    }
}

Выходной сигнал:

Starting new thread...
Thread started. Sleeping
Calling someStaticMethod
Finished sleeping
In someStaticMethod
someStaticMethod returned
In main. Sleeping again.

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

Другие советы

Ты можешь позвонить main() для других объектов из любого другого места вашего кода столько раз, сколько вы захотите.Статический инициализатор будет выполняться только один раз.Кроме того, вы можете передать параметры из командной строки в main().

Два больших плюса за main() в моей книге.

Основная причина, по которой лучше использовать main() заключается в том, что у вас может быть несколько основных методов в вашем приложении (в разных классах).Если вы загружаете класс, main() не выполняется автоматически, пока static блоки кода всегда выполняются ровно один раз при первой загрузке класса, и нет никакого способа предотвратить это.

Хорошо, я признаю, что я не пробовал это со статическим инициализированным классом, но не стал бы вводить

java StaticInitializedClass

в командной строке распечатайте

Exception in thread "main" java.lang.NoSuchMethodError: main

поскольку у него нет main(String[]) способ?

Давайте не будем забывать о ремонтопригодности.Когда кто-то другой собирается изменить ваш код, он всегда будет искать метод main() для запуска программы.Если только нет какой-то причины, по которой вы не можете обойти (а я предполагаю, что это не так), тогда я бы просто использовал метод main.

Если у вас нет никакой точки входа, вы ничего не сможете запустить.Если у вас много точек входа (много основных методов), пользователь, который запускает ваше приложение, управляет им, которое будет запускаться из командной строки.
С другой стороны, блоки статической инициализации выполняются при загрузке класса.Контролировать, какой класс загружается, и порядок загрузки классов (и выполнения их блоков статической инициализации) гораздо сложнее.Это достаточная причина, чтобы не придавать большого значения логике статических блоков инициализации.Вы делаете что-то более трудное для чтения и понимания, а в награду получаете что-то более трудное для использования.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top