Подтвердить что ты не робот

Почему основной метод статичен в java

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

"Правильно ли эта причина?"

Это в какой-то степени, хотя это никогда не объяснялось так точно.

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

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

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

       }
 }

Как факт, Java создает для вас конструктор no-arg, если вы его не укажете, было бы очень легко включить конструктор 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 )

Кстати, вы можете иметь программу Hello! 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!!

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

Ответ 3

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

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

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

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

См. также:

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

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

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

Ответ 7

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

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

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

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

Java немного более прагматична, чем чистый язык OO, имеющий статические методы и поля и примитивные типы. Его статический основной метод ближе к основной функции 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 );
}

Ответ 8

нет необходимости создавать объект для вызова статического метода. Таким образом, нет необходимости в jvm для выделения дополнительной памяти для создания obj main, а затем для вызова.

Ответ 9

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

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

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

Итак, я думаю, что это настоящая причина статической основной функции.

Ответ 10

В java main метод статичен, Java Virtual Machine может вызывать его без создания какого-либо экземпляра класса, который содержит основной метод. Если основной метод не был объявлен статическим, а JVM должен создать экземпляр основного класса, и поскольку конструктор может быть перегружен и может иметь аргументы, для JVM не будет определенного и согласованного способа поиска основного метода в Java.