Tiempo de compilación vs tiempo de Ejecución de la Dependencia de Java

¿Cuál es la diferencia entre el tiempo de compilación y tiempo de ejecución de las dependencias en Java?
Es relativa a la ruta de clase, pero ¿en qué se diferencian?

InformationsquelleAutor Kunal | 2010-11-24

6 Kommentare

  1. 70
    • En tiempo de compilación dependencia: Usted necesita la dependencia en su CLASSPATH para compilar su artefacto. Se producen debido a que usted tiene algún tipo de «referencia» a la dependencia codificado en el código, tales como llamar a new para algunos de la clase, la ampliación o la aplicación de algo (ya sea directa o indirectamente), o una llamada al método con la reference.method() notación.

    • De tiempo de ejecución de la dependencia: Usted necesita la dependencia en su CLASSPATH para ejecutar su artefacto. Se producen debido a ejecutar el código que accede a la dependencia (ya sea en un duro camino o a través de la reflexión o lo que sea).

    Aunque en tiempo de compilación dependencia generalmente implica tiempo de ejecución de la dependencia, usted puede tener un tiempo de compilación única dependencia. Esto se basa en el hecho de que Java sólo los vínculos de la clase de dependencias en el primer acceso a esa clase, así que si usted nunca acceso a una clase en particular en tiempo de ejecución debido a una ruta de código nunca es atravesado, Java ignorar tanto la clase y sus dependencias.

    Ejemplo de este

    En C.java (genera C.class):

    package dependencies;
    public class C { }

    En A.java (genera A.class):

    package dependencies;
    public class A {
        public static class B {
            public String toString() {
                C c = new C();
                return c.toString();
            }
        }
        public static void main(String[] args) {
            if (args.length > 0) {
                B b = new B();
                System.out.println(b.toString());
            }
        }
    }

    En este caso, A tiene un tiempo de compilación dependencia de C a través de B, pero sólo tendrá un tiempo de ejecución de la dependencia de C si se pasan algunos parámetros a la hora de ejecutar java dependencies.A, como la JVM sólo tratar de resolver B‘s la dependencia de C cuando se llega a ejecutar B b = new B(). Esta característica permite que usted proporcione en tiempo de ejecución sólo las dependencias de las clases que utiliza en sus rutas de código, y omitir las dependencias de el resto de las clases en el artefacto.

    • Sé que esto es muy antiguo respuesta, pero, ¿cómo puede la JVM no C como una dependencia de tiempo de ejecución desde el inicio? Si es capaz de reconocer «aquí hay una referencia a la C, tiempo de añadir una dependencia», entonces no C ya esencialmente una dependencia, ya que la JVM lo reconoce y sabe de donde es?
    • Podría haber sido especificado de esa manera, supongo, pero decidieron que pereza vinculación era mejor, y personalmente estoy de acuerdo que la razón se ha dicho: se permite el uso de código si es necesario, pero no te obligan a incluir en su implementación si usted no lo necesita. Que es bastante útil cuando se trata de código de terceros.
    • Si tengo un frasco implementado en algún lugar, sin embargo, ya se va a tener que contener todas las dependencias. No sé si será ejecutar con argumentos o no (por lo que no se sabe si o no C va a ser utilizado), por lo que tendría que tener C a disposición de cualquier manera. Simplemente no veo cómo cualquier memoria/se ahorra tiempo al no tener C en la ruta de clases desde el inicio.
    • un FRASCO no es necesario incluir todas sus dependencias. Que ‘s por qué casi todos los no-trivial de la aplicación tiene un directorio /lib o similares que contengan varios Frascos.
  2. 31

    Un ejemplo fácil es mirar a una api como el servlet api. Para hacer su servlets compilar, usted necesita el servlet-api.jar pero en tiempo de ejecución el contenedor de servlet proporciona un servlet api de la aplicación, de modo que usted no necesita agregar servlet-api.jar a su clase en tiempo de ejecución ruta.

    • Para la aclaración (esto me confunde), si usted está usando maven y la construcción de una guerra, «servlet api» es un «siempre» de la dependencia en lugar de un «tiempo de ejecución» de dependencia, que sería la causa para que se incluya en la guerra, si estoy en lo correcto.
    • ‘siempre’ significa, incluyen en tiempo de compilación, pero no empaquetarlo en la GUERRA o en la colección de las dependencias. ‘runtime’ hace lo contrario (no disponible en la compilación, sino que viene embalado con la GUERRA).
  3. 27

    El compilador necesita el derecho classpath con el fin de compilar las llamadas a una biblioteca (tiempo de compilación dependencias)

    La JVM necesidades de la derecha classpath para cargar las clases en la biblioteca a la que está llamando (dependencias en tiempo de ejecución).

    Que puede ser diferente en un par de formas:

    1) si la clase C1 llamadas de la biblioteca de la clase de L1 y L1 llamadas de la biblioteca de la clase de L2, entonces C1 tiene un tiempo de ejecución de la dependencia en la L1 y la L2, pero sólo un momento de la compilación de dependencia en L1.

    2) si la clase C1 dinámicamente crea una instancia de una interfaz I1 el uso de la Clase.forName() o algún otro mecanismo, y la clase de implementación para la interfaz I1 es la clase de L1, entonces C1 tiene un tiempo de ejecución de la dependencia de I1 y L1, pero sólo un momento de la compilación de dependencia en I1.

    Otros «indirecta» de las dependencias que son de la misma en tiempo de compilación y tiempo de ejecución:

    3) la clase C1 se extiende de la biblioteca de la clase de L1 y L1 implementa la interfaz I1 y se extiende de la biblioteca de la clase de L2: C1 tiene un tiempo de compilación de la dependencia en L1, L2, y I1.

    4) la clase C1 tiene un método foo(I1 i1) y un método bar(L1 l1) donde I1 es una interfaz y L1 es una clase que toma un parámetro, que es la interfaz I1: C1 tiene un tiempo de compilación de la dependencia en I1 y L1.

    Básicamente, hacer algo interesante, la clase necesita para hacer interfaz con otras clases e interfaces en el classpath. La clase/interfaz gráfico formado por el conjunto de la biblioteca interfaces los rendimientos de la compilación de la dependencia del tiempo de la cadena. La biblioteca implementaciones el rendimiento de la ejecución de la dependencia del tiempo de la cadena. Tenga en cuenta que el tiempo de ejecución de la dependencia de cadena de tiempo de ejecución dependiente o fail-lento: si la aplicación de la L1 a veces depende de instanciar un objeto de la clase de L2, y que la clase sólo se ejecuta en un escenario en particular, entonces no hay ninguna dependencia, excepto en ese escenario.

    • No debería el tiempo de compilación de la dependencia en el ejemplo 1 L1?
    • sí, se ha corregido un par de errores tipográficos.
    • Gracias, pero ¿cómo funciona la clase de los trabajos de carga en tiempo de ejecución? En tiempo de compilación es fácil de entender. Pero en tiempo de ejecución, ¿cómo es que la ley, en un caso, cuando tengo dos Frascos de diferentes versiones? Que uno va a elegir?
    • Estoy bastante seguro de que el defecto del cargador de clases se lleva a la ruta de clases y los pasos a través de la misma, en orden, así que si usted tiene dos frascos en el classpath de que ambos contienen la misma clase (por ejemplo, com.ejemplo.fooutils.Foo), se utilizará el uno que es la primera en el classpath. O eso, o usted obtendrá un mensaje de error indicando la ambigüedad. Pero si quieres más información específica para los cargadores de clases usted debe preguntar a una pregunta aparte.
    • Creo que en el primer caso, el tiempo de compilación dependencias deben también estar ahí en la L2 es decir, la frase debería ser: 1) si la clase C1 llamadas de la biblioteca de la clase de L1 y L1 llamadas de la biblioteca de la clase de L2, entonces C1 tiene un tiempo de ejecución de la dependencia en la L1 y la L2, pero sólo un momento de la compilación de dependencia en L1 & L2. Esto es así, como en el tiempo de compilación también cuando el compilador de java verifica L1, entonces también se comprueba todas las otras clases a las que hace referencia L1 (excluyendo la dinámica de las dependencias como de la Clase.forName(«myclassname)) … de lo contrario ¿cómo se verifica que la compilación está trabajando bien. Por favor explique si usted piensa lo contrario
    • No. Usted necesita leer sobre cómo compilación y vinculación de obras en Java. Todas las compilador preocupa, cuando se refiere a una clase, es la forma de con que clase de, por ejemplo, cuáles son sus métodos y campos. No importa lo que realmente sucede en ese externos de la clase de métodos. Si L1 llamadas L2, que es un detalle de implementación de la L1 y L1 ya ha sido compilado en otros lugares.
    • En el segundo párrafo de esta respuesta, es el tiempo de carga de la dependencia, pero no en tiempo de ejecución de la dependencia. Dependencia de tiempo de ejecución es puramente través de la reflexión

  4. 11

    Java en realidad no se nada enlace en tiempo de compilación. Sólo comprueba la sintaxis mediante la coincidencia de las clases se encuentra en el CLASSPATH. No es hasta el tiempo de ejecución que todo se une, y ejecutado a partir de la ruta de clases en ese momento.

    • No es hasta que loadtime… tiempo de ejecución es diferente de loadtime.
  5. 10

    Dependencias en tiempo de compilación son sólo las dependencias (otras clases) que utiliza directamente en la clase que se está compilando. Dependencias en tiempo de ejecución abarca tanto a las dependencias directas e indirectas de la clase que se está ejecutando. Por lo tanto, dependencias en tiempo de ejecución incluye las dependencias de las dependencias y cualquier reflexión dependencias como nombres de clases que usted tiene en un String, pero se usa en el Class#forName().

    • Gracias, pero ¿cómo funciona la clase de los trabajos de carga en tiempo de ejecución? En tiempo de compilación es fácil de entender. Pero en tiempo de ejecución, ¿cómo es que la ley, en un caso, cuando tengo dos Frascos de diferentes versiones? Que clase fuera de Clase.forName() de recogida, en caso de varias clases de diferentes clases en una ruta de clase?
    • El uno que coincida con el nombre del curso. Si la verdad significa «varias versiones de la misma clase», entonces depende de que el cargador de clases. El «más cercano», será cargado.
    • Bueno, yo creo que si usted tiene A.jar con A, B.jar con B extends A y C.jar con C extends B, a continuación, C.jar depende del tiempo de compilación en A.jar aunque C dependencia de Un es indirecta.
    • El problema en todo el tiempo de compilación de las dependencias es interfaz de dependencia (si la interfaz es a través de una clase de métodos, o a través de una interfaz métodos, o a través de un método que contiene un argumento que es una clase o interfaz)
  6. 1

    Para Java, el tiempo de compilación de la dependencia es el código fuente de la dependencia. Por ejemplo, si Una clase llama a un método de la clase B, entonces a es dependiente de a B en el tiempo de compilación, ya que Una tiene que saber acerca de B (tipo B) para ser compilado. El truco aquí debería ser este: código Compilado no es un completo y código ejecutable todavía. Incluye reemplazable direcciones (símbolos, metadatos) de las fuentes de las que aún no están compilados o existente en el exterior de los frascos. Durante la vinculación de las direcciones debe ser sustituido por el real direcciones en la memoria. Para hacerlo correctamente, símbolos correctos/direcciones debe ser creado. Y esto se puede hacer con el tipo de la clase (B). Creo que esa es la principal dependencia en el tiempo de compilación.

    Dependencia de tiempo de ejecución es más relacionados con el flujo de control. Es involes real direcciones de memoria. Es una dependencia que tiene cuando se ejecuta el programa. Usted necesidad de la clase B de los detalles aquí como implementaciones, no sólo el tipo de información. Si la clase no existe, entonces usted va a obtener RuntimeException y JVM va a salir.

    Ambas dependencias, en general, y no debe, el flujo en la misma dirección. Esta es una cuestión de diseño OO, aunque.

    En C++, la compilación es un poco diferente (no es justo-a-tiempo) pero tiene un enlazador demasiado. Por lo que el proceso podría ser considerado similar a Java, supongo.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea