una reconoce proyecto librerias libreria instalar importar dependencias dependencia como añadir agregar java runtime classpath compile-time

java - reconoce - instalar dependencias netbeans



Tiempo de compilación vs tiempo de ejecución Dependencia-Java (6)

¿Cuál es la diferencia entre el tiempo de compilación y las dependencias de tiempo de ejecución en Java? Está relacionado con el camino de clases, pero ¿en qué se diferencian?


El compilador necesita la ruta de clase correcta para compilar las llamadas a una biblioteca (dependencias de tiempo de compilación)

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

Pueden ser diferentes en un par de maneras:

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

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

Otras dependencias "indirectas" que son las mismas para tiempo de compilación y tiempo de ejecución:

3) su clase C1 amplía la clase de biblioteca L1, y L1 implementa la interfaz I1 y amplía la clase de biblioteca L2: C1 depende en tiempo de compilación de 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 en tiempo de compilación de 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 genera la cadena de dependencia en tiempo de compilación. Las implementaciones de la biblioteca producen la cadena de dependencia en tiempo de ejecución. Tenga en cuenta que la cadena de dependencia en tiempo de ejecución es dependiente en tiempo de ejecución o falla lenta: si la implementación de L1 a veces depende de la creación de 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 en realidad no vincula nada en tiempo de compilación. Solo verifica la sintaxis utilizando las clases coincidentes que encuentra en CLASSPATH. No es hasta el tiempo de ejecución que todo se arregla y ejecuta en función de la CLASSPATH en ese momento.


Las dependencias de tiempo de compilación son solo las dependencias (otras clases) que usa directamente en la clase que está compilando. 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 los nombres de clase que tiene en una String , pero que se usan en la Class#forName() .


Para Java, la dependencia del tiempo de compilación es la dependencia del 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 momento de la compilación, ya que A tiene que saber acerca de B (tipo de B) para compilar. El truco aquí debería ser este: el código compilado no es un código completo y ejecutable todavía. Incluye direcciones reemplazables (símbolos, metadatos) para las fuentes que aún no están compiladas o existentes en archivos jar externos. Durante el enlace, 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 dependencia principal en el momento de la compilación.

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

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

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


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


  • Dependencia en tiempo de compilación : necesita la dependencia en su CLASSPATH para compilar su artefacto. Se producen porque tiene algún tipo de "referencia" a la dependencia codificada en el código de su código, como llamar a una clase new , extender o implementar algo (directa o indirectamente), o una llamada a un método usando la reference.method() directa. Método reference.method() notación.

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

Aunque la dependencia en tiempo de compilación generalmente implica dependencia en tiempo de ejecución, puede tener una dependencia solo en tiempo de compilación. Esto se basa en el hecho de que Java solo vincula las dependencias de clase en el primer acceso a esa clase, por lo que si nunca accede a una clase en particular en el tiempo de ejecución porque nunca se recorre una ruta de código, Java ignorará tanto la clase como 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 de tiempo de compilació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 característica le permite proporcionar en tiempo de ejecución solo las dependencias de las clases que utiliza en sus rutas de código, e ignorar las dependencias del resto de las clases en el artefacto.