Почему основной метод статичен в Java [дубликат]

13
задан Jonik 5 July 2010 в 17:38
поделиться

8 ответов

Это просто соглашение. Разработчики языка Java могли легко решить, что вы должны назначить класс для создания экземпляра, сделав его конструктор основным методом. Но вызов статического метода столь же эффективен и не требует предварительного создания экземпляра класса.

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

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

18
ответ дан 1 December 2019 в 20:10
поделиться

«Эта причина верна?»

В некоторой степени это так, хотя это никогда специально не объяснялось.

У нас могло бы быть соглашение, чтобы также вызывать конструктор с String ... args , что означало бы, что вам нужен хотя бы объект для запуска, но (вероятно) дизайнеры посчитали, что это не нужно .

Например, нет технических препятствий для того, чтобы иметь что-то вроде этого:

 class Hello {
       public void main(String...args){
           System.out.println("Hello, world");

       }
 }

Фактически, Java создает для вас конструктор без аргументов, если вы его не укажете, было бы очень легко включить конструктор var args также, если класс содержит основной метод, и создать под капотом следующий код:

 class Hello {
      // created by the compiler
      public Hello(){}
      public Hello( String ... args ) {
          this();
          main( args );
      }
      // end of code created by the compiler
      public void main( String ... args ) {
           System.out.println("Hello, world!");
      }
  }

Но это создаст ненужный код и дополнительный выделенный объект, который в этом случае ничего не сделает; два конструктора (вместо одного) и т. д. В итоге это будет выглядеть как слишком много магии.

Это дело дизайнеров языка.В этом случае они, вероятно, подумали, что будет проще не делать этого и просто проверить, имеет ли вызываемый класс специальную сигнатуру метода под названием public static void main (String [] args)

Кстати, у вас может быть Здравствуйте! world программа на Java без основного метода , , но выдает java.lang.NoSuchMethodError: main

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

$ java WithoutMain
Look ma, no main!!

Я знаю, что это не альтернатива, но все же это интересно не так ли?

5
ответ дан 1 December 2019 в 20:10
поделиться

Я слышал, как некоторые люди говорили: «Если main не является статическим, тогда JVM может создать объект класса, содержащий main, и вызвать этот main через объект.

Это неверно. По крайней мере, это нигде не указано в JLS .

Но проблема в том, как JVM узнает, какой конструктор вызывать в случае перегруженных конструкторов или даже если существует только один параметризованный конструктор, то что передавать »[

Если бы это было правдой, я бы просто ожидал, что он вызовет (неявный) конструктор no-arg по умолчанию.

См. Также:

2
ответ дан 1 December 2019 в 20:10
поделиться

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

И вам не нужна функция main, если вы используете jvm.dll для себя, а просто создаете объект и вызываете его.

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

1
ответ дан 1 December 2019 в 20:10
поделиться

Да, другие языки, работающие на JVM, создают объекты или модули (которые также являются объектами) и запускают их. Например, язык Fortress 'Hello world' выглядит как

Component HelloWorld
Export Executable
run(args) = print "Hello, world!"
end

или, без аргументов:

Component HelloWorld
Export Executable
run() = print "Hello, world!"
end

Java немного более прагматичен, чем чистый объектно-ориентированный язык, имеющий статические методы, поля и примитивные типы.Его статический основной метод ближе к основной функции C. Вы должны спросить Гослинга, почему он выбрал эту конвенцию.

Код для запуска JVM довольно прост - в этом примере создается JVM, создается объект и вызывается его метод run с аргументами командной строки - выполнение функции запуска (new main. HelloWorld ()). Run (args) вместо main.HelloWorld.main (args) :

#include <stdio.h>
#include <jni.h>

JNIEnv* create_vm() {
    JavaVM* jvm;
    JNIEnv* env;
    JavaVMInitArgs args;
    JavaVMOption options[1];

    args.version = JNI_VERSION_1_2;
    args.nOptions = 1;

    options[0].optionString = "-Djava.class.path=C:\\java_main\\classes";
    args.options = options;
    args.ignoreUnrecognized = JNI_TRUE;

    JNI_CreateJavaVM(&jvm, (void **)&env, &args);

    return env;
}

int invoke_class(JNIEnv* env, int argc, char **argv) {
    jclass helloWorldClass;

    helloWorldClass = env->FindClass("main/HelloWorld");

    if (helloWorldClass == 0)
        return 1;

    jmethodID constructorMethod = env->GetMethodID(helloWorldClass, "<init>", "()V");

    jobject object = env->NewObject(helloWorldClass, constructorMethod);

    if (object == 0)
        return 1;

    jobjectArray applicationArgs = env->NewObjectArray(argc, env->FindClass("java/lang/String"), NULL);

    for (int index = 0; index < argc; ++index) {
        jstring arg = env->NewStringUTF(argv[index]);
        env->SetObjectArrayElement(applicationArgs, index, arg);
    }

    jmethodID runMethod = env->GetMethodID(helloWorldClass, "run", "([Ljava/lang/String;)V");

    env->CallVoidMethod(object, runMethod, applicationArgs);

    return 0;
}

int main(int argc, char **argv) {
    JNIEnv* env = create_vm();

    return invoke_class( env, argc, argv );
}
1
ответ дан 1 December 2019 в 20:10
поделиться

Но проблема в том, как JVM узнает, какой конструктор вызывать в случае перегруженных конструкторов или даже если есть только один параметризованный конструктор, что тогда передавать."

Я тоже так думаю. Я не использую Java. Я использую C++. Если вы не пишете конструктор самостоятельно, то по умолчанию вам неявно предоставляется конструктор без аргументов и конструктор копирования. Но если вы пишете конструктор самостоятельно, то компилятор не предоставляет никакого конструктора. Я думаю, что эта теория соблюдается и в Java.

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

Поэтому я думаю, что это и есть истинная причина статической функции Main.

0
ответ дан 1 December 2019 в 20:10
поделиться

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

Вы все еще можете создавать объекты до выполнения main(), если вы создаете их статически.

1
ответ дан 1 December 2019 в 20:10
поделиться

static - это ключевое слово, когда оно применяется перед методом main, JVM будет считать, что это начальная точка выполнения. так почему JVM так думает? java soft people возлагают на JVM ответственность за вход в указанный класс через метод main(). EX: предположим, есть два класса A и B, где B расширяет A, здесь согласно java, для каждого класса должен быть создан объект для доступа к переменным и методам этого класса, здесь в классе B написан статический метод main(), static - слово, которое говорит, что независимо от начала выполнения программы... будет выделена память для этого ключевого слова до начала выполнения программы.

2
ответ дан 1 December 2019 в 20:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: