Por qué Java mola
El otro día estuve viendo una presentación de Kinisoftware en la que dijo que “Java mola”. Al final no explica por qué Java mola, así que he decidido hacerlo yo.
Claro, que al final también diré por qué Java no mola.
Espero que Kinisoftware pueda leer esto y criticarlo con todas sus ganas. Kini: ¡va por ti!
Actualización 2012-06-28: Dándole la razón a Alejandro, confundí el polimorfismo con la sobrecarga de métodos. Corregido. Actualización 2012-06-20: Añado ejemplos de aplicaciones Java que utilizan XML como base, y mejoro la definición de Polimorfismo. También añado la desventaja de que no permite sobrecarga de operadores.
Java mola
Tipado estático
Lo primero que llama la atención de Java es que tiene tipado estático. Este tipado tiene sus ventajas: es más difícil romper algo y sirve como documentación.
El tipado estático permite cosas como la:
Sobrecarga de métodos
Ya que dos funciones con distintos parámetros de entrada pueden distinguirse por sus argumentos, ya sea en tipo o en número. De esta manera, la llamada se ajustará al método que se ajuste a los parámetros con los que se está llamando.
El hecho de utilizar distintos parámetros para seleccionar el método a llamar evita el uso de condiciones innecesarias y facilita el principio de única responsabilidad: un método trabaja con un tipo de datos y otro método, con otro.
Polimorfismo
Podemos sobreescribir un método en una clase hija, de manera que se comporte de forma diferente al padre.
Compilado
Al estar compilado, ya se han realizado una serie de comprobaciones que no es necesario realizar en tiempo de ejecución, como la validez de los argumentos. Esto debería redundar en un código más fiable y rápido.
Binario y empaquetado
El código compilado es binario, lo que facilita la distribución del programa. Además, se puede empaquetar en JARs o WARs, que facilitan aún más su distribución.
Distribución
Existen numerosas herramientas para distribuir los paquetes, entre las que destacan Maven e Ivy. Así no es necesario tener que subir binarios ea nuestros repositorios.
Estas mismas herramientas facilitan la organización del código.
IDEs
Los IDEs existentes son de gran calidad. Además, el tipado estático facilita que los IDEs acierten con sus pronósticos.
Checkers
Hay una multitud de programas que permiten comprobar la bondad del código, ofreciéndonos alternativas óptimas.
Librerías
La librería estándar es muy amplia, pero hay numerosas librerías que permiten ampliarla aún más, como Apache Commons.
Orientado a web
Existen numerosos frameworks para orientarlo a la web: struts, spring, JSF,…
Documentación
La documentación suele ser muy buena y, además, puede embeberse dentro del propio IDE.
Velocidad
Contrariamente a lo que siempre se ha dicho de Java, es rápido. Muy rápido. Lo único que, a menudo, resulta algo más lento es la carga de la JVM.
La versión 1.4 era terrible, pero utilizarla en las comparativas es como comparar cualquier otra cosa funcionando en un 386.
Sublenguajes
Resulta facilísimo añadir otros lenguajes interpretados en nuestros programas Java. De hecho, Java tiene una API para permitir esto.
Por esa razón proliferan tanto los intérpretes: IronPython, Groovy, Clojure,… Java estándar incorpora un intérprete de JavaScript (Rinho).
Gestión de la memoria
Java realiza una eficiente recolección de memoria, con detección de ciclos y todo tipo de optimizaciones.
Java no mola
Tipado estático
El tipado estático complica la generalidad. Para hacer una función genérica, necesitas crearte una clase por cada tipo de dato y una interfaz común a todo ello.
Además, como sólo se permite una clase pública por fichero, esto supone a menudo la creación de, al menos, 4 ficheros (el principal, la interfaz y las dos especializaciones).
Sobrecarga de métodos
Apesar de la posibilidad de sobrecargar métodos, ésta a veces falla, ya que se puede estar utilizando un objeto que encaja en distintos prototipos. Por ejemplo:
|
|
Sobrecarga de operadores
Sin embargo, Java no permite sobrecargar operadores. Esto es una lástima, ya que resulta mucho más gráfico ver un operador que una llamada a una función:
|
|
Intérprete
No tiene un intérprete en línea. El intérprete en línea disponible, beanshell, no forma parte de la distribución de Java estándar. A menudo resulta muy útil para realizar ciertas pruebas o ejecutar pequeños programas.
Complejidad inicial
Un programa mínimo tiene cierta complejidad: Necesitas una clase pública, un método estático, público, con una estructura y nombres fijos, que recibe por argumentos un array estático. Ésta es una de las razones por las que se critica tanto a Java como lenguaje para aprender a programar.
IDEs
Resulta demasiado fácil caer en la trampa de los IDEs y utilizar la gran capacidad de éstos para todo. Así, a menudo olvidamos que estamos importando demasiadas clases, o complicando la arquitectura en exceso.
Distribución
La propia distribución de código puede volverse contra nosotros con facilidad, ya que es fácil crear dependencias cíclicas que programas como Maven no pueden resolver.
Compilación
El proceso de compilación es lento y, encima, no ofrece optimizaciones de código. Es algo que no termino de entender, ya que se supone que es uno de los grandes beneficios.
Si bien es cierto que existen programas a parte que permiten esta optimización del bytecode, no entiendo por qué tarda tanto el compilador en realizar una “simple” traducción de código.
Memoria
Aunque Java realiza muchas comprobaciones, hay algo que es indiscutible: los programas Java consumen muchos recursos.
Hosting
El hosting de programas Java suele requerir una máquina virtual completa, lo que hace que su precio no baje de los 60€.
En los sistemas de pago por recursos, Java requiere muchos recursos para trabajar, por lo que también resulta algo caro.
Sencillez
Casi todo se basa en XML. XML es sencillo para la máquina, pero requiere bastantes recursos para procesarse y no es sencillo para los seres humanos.
Además, el simple hecho de abrir un archivo resulta terriblemente complejo. En las últimas versiones de Java han añadido el tipo FileReader
, que facilita esta labor, pero aún hay muchas APIs en las que se exige un Stream
, haciendo inviable el uso de el FileReader
y teniendo que utilizar modos de carga más antiguos.
Otro tema son las fechas: es horrible trabajar con ellas.
Y también están los getters/setters: ¿Hasta cuándo tendremos que lidiar con ellos? No entiendo por qué complicar una clase cuando puede ser muy sencilla.
Ejemplos de utilidades Java ampliamente extendidas que utilizan XML:
Obsoleto
Hay multitud de clases obsoletas en la API, sobre todo si nos metemos con las fechas. Además, hay muchas máquinas modernas que permiten ejecutar código Java, pero sólo soportan versiones antiguas, como la 1.4 ó 1.5.
Incompetencia
Aunque existen grandísimos profesionales en el mundo de Java, parece que todo es tan sencillo que se favorece la incompetencia. Quizá por eso las grandes corporaciones prefieren Java a otros lenguajes.
Java permite un uso muy apropiado, mediante la aplicación de patrones, reutilización, etc. Sin embargo las grandes corporaciones prefiren tener monos picando código y parece que Java es apropiado para este uso.
Por favor, si usáis Java, no seáis monos.
Ficheros
Es terrible cómo aumenta la cantidad de ficheros cuando estamos programando en Java. A menudo resulta difícil seguir tantos archivos si no es con un IDE.
También es común que los desarrolladores traten de sobrecargar de funcionalidad una clase sólo por evitar tener que crear otro archivo. De verdad: la orientación a objetos se entiende de verdad cuando se aplica el principio de única responsabilidad.
Fin
Son muchas las razones para usar y para no usar Java. Aquí tan sólo he tratado de recopilarlas. Seguramente me deje muchas de ellas en el tintero.
Si se te ocurre algo, por favor, coméntalo. No te preocupes si estás tirando piedras sobre tu propio tejado: siempre es bueno conocer el alcance de tus herramientas.
Y es precisamente por esta razón por la que el título del artículo de la semana que viene será por qué Python mola.