Tiempo de comstackción vs Dependencia de tiempo de ejecución – Java

¿Cuál es la diferencia entre el tiempo de comstackción y las dependencias de tiempo de ejecución en Java? Está relacionado con la ruta de clase, pero ¿cómo difieren?

  • Dependencia en tiempo de comstackción : necesita la dependencia en su CLASSPATH para comstackr su artefacto. Se producen porque tiene algún tipo de “referencia” a la dependencia codificada en su código, como llamar a algo new para alguna clase, extender o implementar algo (ya sea directa o indirectamente), o una llamada a un método utilizando el método reference.method() directo reference.method() notación.

  • Dependencia en tiempo de ejecución : necesita la dependencia en su CLASSPATH para ejecutar su artefacto. Se producen porque se ejecuta código que accede a la dependencia (ya sea de forma codificada o mediante reflexión o lo que sea).

Aunque la dependencia del tiempo de comstackción suele implicar una dependencia de tiempo de ejecución, puede tener una dependencia de solo tiempo de comstackción. Esto se basa en el hecho de que Java solo vincula dependencias de clase en el primer acceso a esa clase, por lo que si nunca se accede a una clase particular en tiempo de ejecución porque una ruta de código nunca se cruza, Java ignorará la clase y sus dependencias.

Ejemplo de esto

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 una dependencia en tiempo de comstackción de C a B , pero solo tendrá una dependencia de tiempo de ejecución en C si pasa algunos parámetros al ejecutar java dependencies.A , ya que la JVM solo intentará resolver B ‘ s dependencia de C cuando llega a ejecutar B b = new B() . Esta función le permite proporcionar en tiempo de ejecución solo las dependencias de las clases que utiliza en las rutas de acceso de códigos e ignorar las dependencias del rest de las clases en el artefacto.

Un ejemplo fácil es mirar una api como la astackción servlet. Para comstackr sus servlets, necesita el servlet-api.jar, pero en tiempo de ejecución, el contenedor de servlets proporciona una implementación api de servlet, por lo que no necesita agregar servlet-api.jar a su ruta de clase de tiempo de ejecución.

El comstackdor necesita la ruta de clases correcta para comstackr llamadas a una biblioteca (comstackciones de tiempo)

La JVM necesita la ruta de clases correcta para cargar las clases en la biblioteca a la que llama (dependencias de tiempo de ejecución).

Pueden ser diferentes en un par de formas:

1) si su clase C1 llama a la clase de biblioteca L1, y L1 llama a la clase de biblioteca L2, entonces C1 tiene una dependencia de tiempo de ejecución en L1 y L2, pero solo una dependencia de tiempo de comstackción en L1.

2) si su clase C1 instancia dinámicamente una interfaz I1 usando Class.forName () o algún otro mecanismo, y la clase implementadora para la interfaz I1 es de clase L1, entonces C1 tiene una dependencia de tiempo de ejecución en I1 y L1, pero solo una dependencia de tiempo de comstackción en I1.

Otras dependencias “indirectas” que son las mismas para el tiempo de comstackción y el tiempo de ejecución:

3) su clase C1 amplía la clase de biblioteca L1, y L1 implementa la interfaz I1 y extiende la clase de biblioteca L2: C1 tiene una dependencia de tiempo de comstackción en L1, L2 e I1.

4) su clase C1 tiene un método foo(I1 i1) y una bar(L1 l1) métodos 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 una dependencia de tiempo de comstackción en I1 y L1.

Básicamente, para hacer algo interesante, su clase necesita interactuar con otras clases e interfaces en el classpath. El gráfico de clase / interfaz formado por ese conjunto de interfaces de biblioteca produce la cadena de dependencia en tiempo de comstackción. Las implementaciones de la biblioteca producen la cadena de dependencia en tiempo de ejecución. Tenga en cuenta que la cadena de dependencias en tiempo de ejecución depende del tiempo de ejecución o falla lenta: si la implementación de L1 a veces depende de crear instancias de un objeto de clase L2, y esa clase solo se instancia en un escenario particular, entonces no hay dependencia, excepto en ese escenario

Java no vincula realmente nada en tiempo de comstackción. Solo verifica la syntax utilizando las clases coincidentes que encuentra en CLASSPATH. No es hasta el tiempo de ejecución que todo se ensambla y se ejecuta según CLASSPATH en ese momento.

Las dependencias de comstackción son solo las dependencias (otras clases) que utiliza directamente en la clase que está comstackndo. Las dependencias de tiempo de ejecución cubren las dependencias directas e indirectas de la clase que está ejecutando. Por lo tanto, las dependencias de tiempo de ejecución incluyen dependencias de dependencias y cualquier dependencia de reflexión como nombres de clase que tenga en una String , pero que se usan en la Class#forName() .

Para Java, la dependencia del tiempo de comstackción es la dependencia de su código fuente. Por ejemplo, si la clase A llama a un método de la clase B, entonces A depende de B en el tiempo de comstackción, ya que A tiene que saber acerca de B (tipo de B) que se comstackrá. El truco aquí debería ser este: el código comstackdo todavía no es un código completo y ejecutable. Incluye direcciones reemplazables (símbolos, metadatos) para las fonts que aún no están comstackdas o que existen en archivos jar externos. Durante la vinculación, esas direcciones deben ser reemplazadas por direcciones reales en la memoria. Para hacerlo correctamente, se deben crear los símbolos / direcciones correctos. Y esto se puede hacer con el tipo de la clase (B). Creo que esa es la principal dependencia en el momento de la comstackción.

La dependencia del tiempo de ejecución está más relacionada con el flujo de control real. Invoca direcciones de memoria reales. Es una dependencia que tienes cuando tu progtwig se está ejecutando. Necesita detalles de clase B aquí como implementaciones, no solo la información de tipo. Si la clase no existe, obtendrá RuntimeException y JVM saldrá.

Ambas dependencias, generalmente y no deberían, fluyen en la misma dirección. Sin embargo, esta es una cuestión de diseño OO.

En C ++, la comstackción es un poco diferente (no solo en el tiempo) pero también tiene un enlazador. Entonces, creo que el proceso podría ser similar a Java.