HOWTO · Java
Función en línea de Java
Java no tiene una declaración de función `inline` en el código fuente. El artículo explica cómo la JVM puede insertar llamadas a métodos durante la ejecución y compara ese cálculo con instrucciones equivalentes.
En esta página
Java no tiene una declaración de función inline en el código fuente. Quienes buscan una función inline en Java suelen referirse a la inserción de métodos: una optimización en tiempo de ejecución en la que una JVM puede sustituir una llamada a un método por las instrucciones de ese método. Se escriben métodos Java normales; la JVM decide durante la ejecución del programa si inserta las llamadas.
¿Qué es la inserción de métodos en Java?
Una llamada a un método normalmente transfiere el control al método y devuelve su resultado. La inserción puede eliminar esa llamada del código máquina compilado al colocar las instrucciones del método en el punto de llamada. Es una optimización de la JVM, no un cambio en el código fuente Java ni algo que se haga copiando código manualmente. El compilador de Java sigue compilando el código fuente en archivos de clase, y la JVM continúa a cargo de la ejecución y la optimización en tiempo de ejecución.
La inserción tampoco significa que todos los métodos se expandan en todas partes. El entorno de ejecución debe preservar el comportamiento del programa y puede mantener una llamada cuando no conviene insertarla. Escribe métodos claros y deja que la JVM tome esta decisión de implementación.
Cómo realiza la JVM HotSpot la inserción de métodos
El compilador justo a tiempo (JIT) de HotSpot puede insertar llamadas elegibles a métodos como parte de la optimización en tiempo de ejecución. La decisión depende del código y de las condiciones de ejecución; no es una garantía del lenguaje Java. Por tanto, no des por hecho que la inserción está siempre habilitada en todas las JVM ni dependas de una opción específica de una implementación para que este ejemplo funcione. El ejemplo siguiente muestra cálculos equivalentes, pero no controla ni revela lo que HotSpot compila internamente.
Crear un ejemplo Java que compare una llamada a un método con instrucciones equivalentes
El primer cálculo llama a addBonus y luego a score. El segundo realiza directamente la misma operación aritmética. Ambos parten del mismo valor, así que se pueden comparar sus resultados sin afirmar que la JVM haya insertado realmente ninguna de las llamadas.
Ejecuta este ejemplo. Las etiquetas visibles de la salida se mantienen en inglés porque forman parte de un bloque inmutable:
public class Main {
static int addBonus(int score) {
return score + 2;
}
static int score(int value) {
return value * 3;
}
public static void main(String[] args) {
int byMethodCalls = score(addBonus(4));
int value = 4;
int byStatements = (value + 2) * 3;
System.out.println("Method calls: " + byMethodCalls);
System.out.println("Direct statements: " + byStatements);
}
}
Method calls: 18
Direct statements: 18
Compilar y ejecutar el ejemplo
Guarda el código fuente como Main.java en un directorio de trabajo vacío. Desde allí, compílalo y ejecútalo con un JDK disponible en tu PATH:
Ejecuta javac Main.java y luego java Main desde ese directorio. Estos comandos corresponden al nombre de clase y al nombre de archivo indicados arriba, y no requieren opciones de ajuste de la JVM. La ejecución proporcionada de este ejemplo exacto finalizó correctamente y mostró la salida indicada arriba.
Qué muestran y qué no muestran los resultados
Al ejecutar el programa, compara los dos valores impresos: deberían coincidir porque las llamadas a métodos y la expresión directa usan la misma operación aritmética. Eso demuestra que los resultados de este pequeño ejemplo son equivalentes. No indica si la JVM insertó alguno de los métodos. Que los valores coincidan tampoco dice cuál de las formas se ejecuta más rápido; para medir el rendimiento haría falta un benchmark controlado aparte. En resumen, usa métodos Java normales para mantener un código fuente legible y considera la inserción una posible optimización en tiempo de ejecución, no una característica que se declare ni un resultado de rendimiento que pueda deducirse de esta salida.