¿Por qué Java no pone el nombre del archivo en argumentos?

20

En C y C ++, el método principal mantiene el nombre del archivo en la primera posición de la matriz en argv [0]. Sin embargo, en Java, el nombre del archivo no se incluye en la matriz de cadenas de argumentos.

¿Hay alguna razón práctica para esto? Entiendo que esto hace que la iteración a través de argumentos de la línea de comandos se base en 0 en lugar de en 1, pero ¿hay algún beneficio? ¿Se consideró que el nombre de archivo era inútil?

Jordan L
fuente

Respuestas:

17

En algunos casos, un programa puede ejecutarse de diferentes maneras y exhibir un comportamiento diferente sobre cómo se llama. Si llama vimcomo vi, se ejecuta en un modo de compatibilidad. A veces es para tratar de mantener una versión de varios programas relacionados, por ejemplo, mailqy newaliasesen muchos sistemas Unix hay un enlace para sendmailque estos programas permanezcan sincronizados)


Los programas Java generalmente se invocan como:

% java -jar foo.jar args
% java Foo args

La primera versión es donde tiene un archivo Manifiesto que indica la clase principal, la segunda versión ejecuta el método principal en la clase que se Fooencuentra en la ruta de clase.

La información presentada para Java es una ruta al jar o el nombre de la clase que se invoca.

La ubicación del jar no es lo suficientemente importante como para ser algo para codificar (y en realidad no era parte de la especificación original). Un Jar puede llamarse realmente cualquier cosa, y a menudo incluye números de versión. Además, no hay garantía de que la clase se haya almacenado en un archivo .jar (podría haberse extraído).

Invocar una aplicación Java -jarsolo tiene una forma de ingresarla: la clase definida en el Manifiesto. No hay cambio de nombre que se pueda hacer.

La otra opción, invocarlo con el nombre de la clase apunta directamente a la unidad de ejecución. Además, no se puede nombrar multiplicar, no puede haber Bar.classsido el código porque class Foosimplemente no funciona de esa manera.

Esto debería mostrar que realmente no tiene sentido pasar la información argv[0]en sentido C a una aplicación Java, ya sea javasin sentido y arbitraria, o el nombre de la clase que se invoca (que ya está ejecutando código) de (podrías hacer algo como getClass().getEnclosingClass().getName()si estuvieras desesperado ...)).

Aquí hay un punto, puede definir múltiples métodos Main en clases en un .jar o en la ruta de clase. Y podría hacer que se comporten de manera diferente como si hubiera una serie de declaraciones if basadas en lo que argv[0]era.

En el pasado, tuve un código similar al java -cp Foo.jar com.me.foo.Testque invocaba el Testmétodo Main de la clase en lugar del que se definió en el definido en el Manifiesto.


fuente
Tiene que haber más que eso. En C #, los parámetros no contienen el nombre del archivo, pero la aplicación generalmente se ejecuta directamente, solo foo.exe.
svick
@svick No estoy familiarizado con C #, ni con cómo se empaqueta un exe. En algunos sistemas operativos, puede hacer que un jar sea ejecutable (vea esto ) que inicia el punto de entrada definido en el Manifiesto. Se pueden hacer cosas similares para C #. La clave es que no puede cambiar el punto de entrada cambiando el nombre del archivo, y el nombre del archivo no está destinado a ser utilizado por ninguna otra parte de la aplicación (fuera del cargador de clases).
@nqzero ( contexto ): si especifico java com.me.Foocomo línea de comando, com.me.Foo.main(String...)se invoca el método . No hay forma de evitar eso. Y sé que se está invocando a Foo, no hay razón para pegar eso en argv. Sería información puramente redundante. Claro, podría estar en la superclase, pero tengo la oportunidad trivial de interceptarlo con la información deseada de cuál era la invocación de la línea de comando; no es necesario ponerlo en argv.
... y recuerde obtener 50 repeticiones y comentarios en lugar de sugerir modificaciones a la respuesta. Es una forma muy pobre de plantear problemas con una publicación determinada.
A veces el comportamiento es radicalmente diferente. wput por ejemplo es en realidad wget.
mckenzm
-4

en realidad no tiene ningún beneficio, realmente depende de la sintaxis del lenguaje de programación que esté utilizando si está basado en 0 o en 1. la variable (a la que se refiere como nombre de archivo) también depende del idioma, puede ser diferente en otros idiomas, solo siga la sintaxis correcta del idioma que está utilizando.

usuario2723735
fuente
1
¿Cómo responde esto a la pregunta que se hace?
mosquito