interfaz grafica ejemplos crear componentes como clase java static main

java - grafica - swing containers netbeans



¿Por qué el método principal de Java es estático? (30)

La firma del método de un método main () de Java es:

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

¿Hay alguna razón para que este método sea estático?


Las palabras clave vacías estáticas públicas significan que el intérprete de la máquina virtual Java (JVM) puede llamar al método principal del programa para iniciar el programa (público) sin crear una instancia de la clase (estática), y el programa no devuelve datos al intérprete Java VM (vacío) cuando termine.

Fuente: Essentials, Parte 1, Lección 2: Creación de aplicaciones


¿Por qué public static void main (String [] args)?

Así es como Java Language está diseñado y Java Virtual Machine está diseñado y escrito.

Especificación del lenguaje Java de Oracle

Echa un vistazo a la Ejecución del Capítulo 12 - Sección 12.1.4 Invocar Test.main :

Finalmente, una vez completada la inicialización para la prueba de clase (durante la cual pueden haber ocurrido otras cargas, enlaces e inicializaciones consecuentes), se invoca el método main de la prueba.

El método main debe ser declarado público, estático y nulo. Debe aceptar un solo argumento que sea una matriz de cadenas. Este método puede ser declarado como

public static void main(String[] args)

o

public static void main(String... args)

Especificación de la máquina virtual Java de Oracle

Consulte el Capítulo 2: Conceptos del lenguaje de programación Java - Sección 2.17 Ejecución :

La máquina virtual de Java comienza la ejecución invocando el método main de alguna clase específica y pasándole un solo argumento, que es una matriz de cadenas. Esto hace que la clase especificada se cargue (§2.17.2), se vincule (§2.17.3) a otros tipos que utiliza, y se inicialice (§2.17.4). El método main debe ser declarado público, estático y nulo.

Oracle OpenJDK Fuente

Descargue y extraiga el ../launcher/java.c fuente y vea cómo se escribe la JVM. Consulte ../launcher/java.c , que contiene el código C nativo detrás del comando java [-options] class [args...] :

/* * Get the application''s main class. * ... ... */ if (jarfile != 0) { mainClassName = GetMainClassName(env, jarfile); ... ... mainClass = LoadClass(env, classname); if(mainClass == NULL) { /* exception occured */ ... ... /* Get the application''s main method */ mainID = (*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V"); ... ... { /* Make sure the main method is public */ jint mods; jmethodID mid; jobject obj = (*env)->ToReflectedMethod(env, mainClass, mainID, JNI_TRUE); ... ... /* Build argument array */ mainArgs = NewPlatformStringArray(env, argv, argc); if (mainArgs == NULL) { ReportExceptionDescription(env); goto leave; } /* Invoke main method. */ (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); ... ...


¿Cuál es el significado de public static void main(String args[]) ?

  1. public es un especificador de acceso, lo que significa que cualquier persona puede acceder o invocarlo, como JVM (Java Virtual Machine).
  2. static permite que main() se llame antes de que se haya creado un objeto de la clase. Esto es necesario porque main() es llamado por la JVM antes de crear cualquier objeto. Como es estático, puede invocarse directamente a través de la clase.

    class demo { private int length; private static int breadth; void output(){ length=5; System.out.println(length); } static void staticOutput(){ breadth=10; System.out.println(breadth); } public static void main(String args[]){ demo d1=new demo(); d1.output(); // Note here output() function is not static so here // we need to create object staticOutput(); // Note here staticOutput() function is static so here // we needn''t to create object Similar is the case with main /* Although: demo.staticOutput(); Works fine d1.staticOutput(); Works fine */ } }

    De manera similar, usamos estática en algún momento para los métodos definidos por el usuario, por lo que no necesitamos hacer objetos.

  3. void indica que el método main() que se está declarando no devuelve un valor.

  4. String[] args especifica el único parámetro en el método main() .

    args : un parámetro que contiene una matriz de objetos del tipo de clase String .


Antes de llamar al método principal, no se crea una instancia de los objetos. Tener la palabra clave estática significa que se puede llamar al método sin crear ningún objeto primero.


Creo que la palabra clave ''estática'' hace que el método principal sea un método de clase, y los métodos de clase tienen solo una copia y pueden ser compartidos por todos, y además, no requiere un objeto como referencia. Entonces, cuando se compila la clase de controlador, se puede invocar el método principal. (Estoy solo en el nivel alfabético de java, perdón si estoy equivocado)


Cuando ejecuta la Máquina Virtual Java (JVM) con el comando java ,

java ClassName argument1 argument2 ...

Cuando ejecuta su aplicación, especifica su nombre de clase como un argumento para el comando java, como anteriormente

La JVM intenta invocar el método principal de la clase que especifique

—En este punto, no se han creado objetos de la clase.

Declarar main como static allows JVM invoke main without crear una instance de la clase.

volvamos al comando

ClassName es un command-line argument para la JVM que le indica qué clase ejecutar. Después de ClassName, también puede especificar una list of Strings (separadas por espacios) como argumentos de línea de comando que la JVM pasará a su aplicación. -Tales argumentos podrían usarse para especificar opciones (por ejemplo, un nombre de archivo) para ejecutar la aplicación. Es por esto que hay un parámetro llamado String[] args en el main

Referencias: Java ™ Cómo programar (objetos tempranos), Décima edición


Déjame explicarte estas cosas de una manera mucho más simple:

public static void main(String args[])

Todas las aplicaciones Java, excepto los applets, inician su ejecución desde main() .

La palabra clave public es un modificador de acceso que permite llamar al miembro desde fuera de la clase.

static se usa porque permite que main() sea ​​llamado sin tener que instanciar una instancia particular de esa clase.

void indica que main() no devuelve ningún valor.


De no ser así, ¿qué constructor debería usarse si hay más de uno?

Hay más información sobre la inicialización y ejecución de los programas Java disponibles en la Especificación del lenguaje Java .


El método es estático porque de lo contrario habría ambigüedad: ¿a qué constructor debería llamarse? Especialmente si tu clase se ve así:

public class JavaClass{ protected JavaClass(int x){} public void main(String[] args){ } }

¿Debería la JVM llamar a una new JavaClass(int) ? ¿Qué debería pasar por x ?

Si no, ¿debería JVM crear JavaClass instancia de JavaClass sin ejecutar ningún método de construcción? Pienso que no debería, porque eso será un caso especial para toda su clase; a veces tiene una instancia que no se ha inicializado y debe verificarla en todos los métodos a los que se pueda llamar.

Hay demasiados casos de borde y ambigüedades para que tenga sentido que la JVM tenga que instanciar una clase antes de llamar al punto de entrada. Es por eso que main es estático.

No tengo ni idea de por qué main siempre está marcado como public .


El método main () en C ++, C # y Java son estáticos porque pueden ser invocados por el motor de tiempo de ejecución sin tener que crear una instancia de la clase principal.


El protoype public static void main(String[]) es una convención definida en el JLS :

El método main debe ser declarado público, estático y nulo. Debe especificar un parámetro formal (§8.4.1) cuyo tipo declarado es una matriz de String.

En la especificación JVM 5.2. Arranque de Máquina Virtual podemos leer:

La máquina virtual de Java se inicia creando una clase inicial, que se especifica de una manera dependiente de la implementación, utilizando el cargador de clases de rutina (§5.3.1). La máquina virtual Java luego vincula la clase inicial, la inicializa e invoca el método de clase pública void main (String []) . La invocación de este método impulsa todas las ejecuciones posteriores. La ejecución de las instrucciones de la máquina virtual Java que constituyen el método principal puede causar la vinculación (y, en consecuencia, la creación) de clases e interfaces adicionales, así como la invocación de métodos adicionales.

Lo curioso es que, en la especificación JVM, no se menciona que el método principal tiene que ser estático. Pero la especificación también dice que la máquina virtual Java realiza 2 pasos antes:

La inicialización de una clase o interfaz consiste en ejecutar su método de inicialización de clase o interfaz.

En el 2.9. Métodos especiales :

Se define un método de inicialización de clase o interfaz :

Una clase o interfaz tiene a lo sumo un método de inicialización de clase o interfaz y se inicializa (§5.5) invocando ese método. El método de inicialización de una clase o interfaz tiene el nombre especial <clinit> , no <clinit> argumentos y es nulo.

Y un método de inicialización de clase o interfaz es diferente de un método de inicialización de instancia definido de la siguiente manera:

En el nivel de la máquina virtual Java, cada constructor escrito en el lenguaje de programación Java (JLS §8.8) aparece como un método de inicialización de instancia que tiene el nombre especial <init> .

Por lo tanto, la JVM inicializa un método de inicialización de clase o interfaz y no un método de inicialización de instancia que sea realmente un constructor. Por lo tanto, no necesitan mencionar que el método principal debe ser estático en la especificación de JVM porque está implícito en el hecho de que no se crea una instancia antes de llamar al método principal.


El verdadero punto de entrada a cualquier aplicación es un método estático. Si el lenguaje Java admitía un método de instancia como el "punto de entrada", entonces el tiempo de ejecución necesitaría implementarlo internamente como un método estático que construyó una instancia del objeto seguido de una llamada al método de instancia.

Con eso fuera del camino, examinaré las razones para elegir una específica de las siguientes tres opciones:

  1. Un static void main() como lo vemos hoy.
  2. Un método de instancia void main() invocado en un objeto recién construido.
  3. Utilizando el constructor de un tipo como punto de entrada (por ejemplo, si la clase de entrada se llamara Program , la ejecución consistiría efectivamente en un new Program() ).

Descompostura:

static void main()

  1. Llama al constructor estático de la clase envolvente.
  2. Llama al método estático main() .

void main()

  1. Llama al constructor estático de la clase envolvente.
  2. Construye una instancia de la clase adjunta al llamar efectivamente a new ClassName() .
  3. Llama al método de instancia main() .

new ClassName()

  1. Llama al constructor estático de la clase envolvente.
  2. Construye una instancia de la clase (entonces no hace nada con ella y simplemente regresa).

Razón fundamental:

Voy a ir en orden inverso para este.

Tenga en cuenta que uno de los objetivos de diseño de Java era enfatizar (requerir cuando sea posible) buenas prácticas de programación orientadas a objetos. En este contexto, el constructor de un objeto inicializa el objeto, pero no debe ser responsable del comportamiento del objeto. Por lo tanto, una especificación que proporcionó un punto de entrada de new ClassName() confundiría la situación para los nuevos desarrolladores de Java al forzar una excepción al diseño de un constructor "ideal" en cada aplicación.

Al hacer main() un método de instancia, el problema anterior se resuelve sin duda. Sin embargo, crea complejidad al requerir que la especificación enumere la firma del constructor de la clase de entrada, así como la firma del método main() .

En resumen, especificar un static void main() crea una especificación con la menor complejidad al tiempo que se adhiere al principio de colocar el comportamiento en los métodos . Teniendo en cuenta lo sencillo que es implementar un método main() que a su vez construye una instancia de una clase y llama a un método de instancia, no existe una ventaja real para especificar main() como un método de instancia.


Es sólo una convención. La JVM ciertamente podría lidiar con métodos principales no estáticos si esa hubiera sido la convención. Después de todo, puede definir un inicializador estático en su clase y crear una instancia de miles de objetos antes de llegar a su método main ().


Es solo una convención, pero probablemente más conveniente que la alternativa. Con una principal estática, todo lo que necesita saber para invocar un programa Java es el nombre y la ubicación de una clase. Si no fuera estático, también tendría que saber cómo crear una instancia de esa clase, o requerir que la clase tenga un constructor vacío.


Esto es sólo una convención. De hecho, incluso el nombre main () y los argumentos pasados ​​son puramente convencionales.

Cuando ejecutas java.exe (o javaw.exe en Windows), lo que realmente sucede es un par de llamadas a la interfaz nativa de Java (JNI). Estas llamadas cargan la DLL que realmente es la JVM (así es, java.exe NO es la JVM). JNI es la herramienta que utilizamos cuando tenemos que salvar el mundo de las máquinas virtuales y el mundo de C, C ++, etc. Lo contrario también es cierto: no es posible (al menos que yo sepa) obtener una JVM ejecutándose sin usar JNI.

Básicamente, java.exe es una aplicación C muy simple que analiza la línea de comandos, crea una nueva matriz de cadenas en la JVM para contener esos argumentos, analiza el nombre de clase que especificó que contiene main (), usa llamadas JNI para encontrar el El método main () en sí, luego invoca el método main (), pasando la matriz de cadenas recién creada como un parámetro. Esto es muy, muy parecido a lo que haces cuando usas la reflexión de Java: en su lugar, simplemente utiliza llamadas a funciones nativas de forma confusa.

Sería perfectamente legal para usted escribir su propia versión de java.exe (la fuente se distribuye con el JDK) y hacer que haga algo completamente diferente. De hecho, eso es exactamente lo que hacemos con todas nuestras aplicaciones basadas en Java.

Cada una de nuestras aplicaciones Java tiene su propio lanzador. Principalmente, hacemos esto para obtener nuestro propio ícono y nombre de proceso, pero ha sido útil en otras situaciones en las que queremos hacer algo además de la llamada main () normal para que todo funcione (por ejemplo, en un caso lo estamos haciendo). Interoperabilidad COM, y en realidad pasamos un identificador COM a main () en lugar de una matriz de cadenas).

Entonces, largo y corto: la razón por la que es estático es porque es conveniente. La razón por la que se llama "principal" es que tenía que ser algo, y main () es lo que hicieron en los viejos días de C (y en esos días, el nombre de la función era importante). Supongo que java.exe podría haberle permitido especificar un nombre de método principal completamente calificado, en lugar de solo la clase (java com.mycompany.Foo.someSpecialMain), pero eso hace que sea más difícil en los IDEs detectar automáticamente el '' Clases lanzables ''en un proyecto.


Los applets, midlets, servlets y beans de varios tipos se construyen y luego se les llama métodos de ciclo de vida. Invocar main es todo lo que se hace a la clase main, por lo que no es necesario que un estado se mantenga en un objeto al que se llama varias veces. Es bastante normal colocar main en otra clase (aunque no es una gran idea), lo que dificultaría el uso de la clase para crear el objeto principal.


Porque de lo contrario, necesitaría una instancia del objeto a ejecutar. Pero se debe llamar desde cero, sin construir el objeto primero, ya que generalmente es tarea de la función main () (bootstrap), analizar los argumentos y construir el objeto, generalmente usando estos argumentos / parámetros de programa.


Recientemente, una pregunta similar ha sido publicada en Programmers.SE

TL;DR parte de la respuesta aceptada es,

En Java, la razón del public static void main(String[] args) es que

  1. Gosling quería
  2. el código escrito por alguien experimentado en C (no en Java)
  3. para ser ejecutado por alguien acostumbrado a ejecutar PostScript en NeWS


Para C #, el razonamiento es transitivamente similar, por así decirlo. Los diseñadores de idiomas mantuvieron la sintaxis del punto de entrada del programa familiar para los programadores procedentes de Java. Como dice el arquitecto C # Anders Hejlsberg ,

... nuestro enfoque con C # simplemente ha sido ofrecer una alternativa ... a los programadores de Java ...

...


Si el método principal no fuera estático, necesitaría crear un objeto de su clase principal desde fuera del programa. ¿Cómo te gustaría hacer eso?


Simplemente simulemos que esa static no sería necesaria como punto de entrada de la aplicación.

Una clase de aplicación se vería así:

class MyApplication { public MyApplication(){ // Some init code here } public void main(String[] args){ // real application code here } }

La distinción entre el código del constructor y el método main es necesaria porque, en OO, un constructor solo se asegurará de que la instancia se inicialice correctamente. Después de la inicialización, la instancia se puede utilizar para el "servicio" deseado. Poner el código completo de la aplicación en el constructor estropearía eso.

Entonces, este enfoque forzaría tres contratos diferentes en la aplicación:

  • Debe haber un constructor por defecto. De lo contrario, la JVM no sabría a qué constructor llamar y qué parámetros deberían proporcionarse.
  • Debe haber un método main 1 . Ok, esto no es sorprendente.
  • La clase no debe ser abstract . De lo contrario, la JVM no podría instanciarlo.

Por otro lado, el enfoque static solo requiere un contrato:

  • Debe haber un método main 1 .

Aquí no importan ni los constructores abstract ni los múltiples.

Dado que Java fue diseñado para ser un lenguaje simple para el usuario, no es sorprendente que también el punto de entrada de la aplicación haya sido diseñado de manera simple utilizando un contrato y no de manera compleja utilizando tres contratos independientes y quebradizos.

Tenga en cuenta: este argumento no se trata de simplicidad dentro de la JVM o dentro de la JRE. Este argumento es sobre la simplicidad para el usuario .

1 Aquí la firma completa cuenta como un solo contrato.

main () es estático porque; en ese punto del ciclo de vida de la aplicación, la pila de la aplicación es de naturaleza procesal debido a que aún no hay objetos instanciados.

Es una pizarra limpia. Su aplicación se está ejecutando en este punto, incluso sin que se haya declarado ningún objeto (recuerde, hay patrones de codificación OO y de procedimiento). Usted, como desarrollador, convierte la aplicación en una solución orientada a objetos creando instancias de sus objetos y dependiendo del código compilado en ellos.

Orientado a objetos es genial por millones de razones obvias. Sin embargo, se han acabado los días en que la mayoría de los desarrolladores de VB usaban regularmente palabras clave como "goto" en su código. "goto" es un comando de procedimiento en VB que se reemplaza por su contraparte OO: invocación de método.

También puede ver el punto de entrada estático (principal) como libertad pura. Si Java hubiera sido lo suficientemente diferente para crear una instancia de un objeto y presentarle solo esa instancia en ejecución, no tendría otra opción PERO para escribir una aplicación de procedimiento. Por inimaginable que pueda parecer para Java, es posible que haya muchos escenarios que requieran enfoques de procedimientos.

Esta es probablemente una respuesta muy oscura. Recuerde, "clase" es solo una colección de código interrelacionado. "Instancia" es una generación autónoma aislada, viva y que respira de esa clase.


Es solo una convención como podemos ver aquí:

El método debe declararse público y estático , no debe devolver ningún valor y debe aceptar una matriz de cadenas como parámetro. De forma predeterminada, el primer argumento que no es de opción es el nombre de la clase que se invocará. Se debe usar un nombre de clase completamente calificado. Si se especifica la opción -jar, el primer argumento no opcional es el nombre de un archivo JAR que contiene archivos de recursos y clases para la aplicación, con la clase de inicio indicada por el encabezado de manifiesto de la clase principal.

http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/java.html#description


estático: cuando la JVM realiza una llamada al método principal, no existe ningún objeto para la clase a la que se llama, por lo tanto, debe tener un método estático para permitir la invocación de la clase.


hay una razón simple detrás de esto: porque no se requiere que el objeto llame al método estático, si fuera un método no estático, la máquina virtual Java primero crea el objeto y luego llama al método main () que llevará al problema de la asignación de memoria adicional.


Básicamente, hacemos a aquellos MIEMBROS DE DATOS y FUNCIONES DE LOS MIEMBROS como ESTÁTICOS que no están realizando ninguna tarea relacionada con un objeto. Y en el caso del método principal, lo estamos haciendo como ESTÁTICO porque no tiene nada que ver con el objeto, ya que el método principal siempre se ejecuta ya sea que estemos creando un objeto o no.


Cualquier método declarado como estático en Java pertenece a la clase en sí. Nuevamente, se puede acceder al método estático de una clase particular refiriéndose a la clase comoClass_name.method_name();

Por lo tanto, no es necesario crear una instancia de una clase antes de acceder a un método estático.

Por lo tanto, el método main () se declara staticpara que se pueda acceder a él sin crear un objeto de esa clase.

Desde que guardamos el programa con el nombre de la clase donde está presente el método principal (o desde donde el programa debe comenzar su ejecución, se aplica a las clases sin un main()método () (Nivel Avanzado)). Así que por el camino mencionado anteriormente:

Class_name.method_name();

Se puede acceder al método principal.

En resumen, cuando se compila el programa, busca el main()método que tiene Stringargumentos como: main(String args[])en la clase mencionada (es decir, por el nombre del programa), y ya que al principio no tiene margen para instanciar esa clase, por lo que main () El método se declara como estático.


La publicpalabra clave es un modificador de acceso, que permite al programador controlar la visibilidad de los miembros de la clase. Cuando un miembro de la clase está precedido por public, se puede acceder a ese miembro por un código fuera de la clase en la que se declara.

Lo contrario de publices private, que evita que un miembro sea utilizado por un código definido fuera de su clase.

En este caso, main()debe declararse como public, ya que debe ser llamado por un código fuera de su clase cuando se inicia el programa.

La palabra clave staticpermite main()ser llamada sin tener que instanciar una instancia particular de la clase. Esto es necesario ya que main()es llamado por el intérprete de Java antes de crear cualquier objeto.

La palabra clave voidsimplemente le dice al compilador que main()no devuelve un valor.


La palabra clave estática en el método principal se usa porque no hay ninguna instanciación que tenga lugar en el método principal. Pero el objeto se construye en lugar de la invocación como resultado, usamos la palabra clave estática en el método principal. En jvm, la memoria de contexto se crea cuando la clase se carga en ella. Y todos los miembros estáticos están presentes en esa memoria. si hacemos la estática principal ahora estará en la memoria y será accesible para jvm (class.main (..)), por lo que podemos llamar al método principal sin necesidad de crear un montón.


Los métodos estáticos no requieren ningún objeto. Se ejecuta directamente por lo que se ejecuta directamente.


No sé si la JVM llama al método principal antes de que se ejemplifiquen los objetos ... Pero hay una razón mucho más poderosa por la que el método main () es estático ... Cuando JVM llama al método principal de la clase (por ejemplo, , Persona). Lo invoca por " Person.main () ". Usted ve, la JVM lo invoca por el nombre de la clase. Es por eso que se supone que el método main () es estático y público para que la JVM pueda acceder a él.

Espero que haya ayudado. Si lo hizo, hágamelo saber comentando.