experiencia
Servicios - Sepa lo que Ricardo Devis & Asociados pueden hacer por ustedPublicaciones - Consulte los documentos que ponemos a su disposiciónContacto - Conozca como ponerse en contacto con Ricardo Devis & Asociados
 


RPP junio 1996

El Lenguaje de Programación Java


Ricardo Devis
Botella

Java es “hot”; Java es “in”; Java es “webby”: La invasión lingüística ha comenzado, en todos los sentidos, y penosamente en los peores. Cierto que Java es una buena idea, pero, ¡diantre!, no escandalosamente genial. Los árboles, como en Sherwood, andan muy juntos y hay que talar, o cuando menos apartar vigorosamente unos cuantos para poder apreciar el bosque desde dentro. Olvidemos Internet y centrémonos en Java como lenguaje de programación. ¿El resultado? Helo aquí

 

Nos pretenden insuflar Java por webos [1]: “Simple, orientado-a-objetos, distribuido, interpretado, robusto, seguro, de arquitectura neutra, alta eficacia, multi-hilo y dinámico” es la descripción que Sun procura del lenguaje, y multitud de notas y artículos en el web, así como en revistas y libros, afianzan tal detalle. Y es que la unión de C++, Objective-C, Smalltalk, Internet y Sun ha generado un poutpurri de gran fuerza atractiva. Pero el caso es que internet se ha convertido en el punto de referencia de lo que se anuncia como un lenguaje completo de propósito general, cual parece ser Java. Precisamente el propósito de este artículo es determinar hasta qué punto es Java tal lenguaje de programación, con independencia del visor “Hot Java” (una aplicación al fin y al cabo), de los applets (programillas [2] para internet, cortos para ser fácilmente cargados y distribuidos) y de Internet misma. Como quiera que la euforia reina por doquier, en este artículo me centraré precisamente en los problemas del lenguaje, en esas porciones del mismo no bien definidas o discutibles, así como en sus características más oscuras o pendientes de definición precisa: a fin de cuentas Java necesita de cierta discusión y enfoque crítico, de manera que dejaremos los elogios para un próximo artículo.

LA LEYENDA DEL ORIGEN Y EL ORIGEN DE LA LEYENDA

La niebla de la leyenda ha difuminado en muy poco tiempo el origen de Java, de forma que yo he podido leer más de 10 versiones matizadamente distintas sobre la génesis, concepción y desarrollo de Java. Claro que aparte de los cuentos de Perrault también he oído (de boca de ingenieros de Sun) cómo este fue un proyecto que rebotó durante mucho tiempo por distintos departamentos sin que nadie le prestara ninguna atención, hasta que finalmente encontró su nicho de mercado en la “aldea global” macluhana. Lo mejor es, de cualquier manera, hacer caso omiso de historias que, independientemente de la bondad intelectual de sus protagonistas, pretenden dar carta de naturaleza a la clarividencia industrial y al pasmo volitivo. Porque, ¿qué demonios importa si en realidad Java ha sido generado aleatoriamente por un equipo de monos, extraterrestres o científicos mal pagados? ¿O es que habremos de desechar la penicilina por su origen? La cuestión es si, independientemente de su origen y entorno comercial cuidadosamente medidos, Java nos ofrece soluciones ajustadas a nuestras expectativas.

OTROS LENGUAJES, OTROS ÁMBITOS

Dícese que Java es entre 10 y 30 veces más lento que C, mientras que Jeff Sutherland afirma que “La belleza de Java es que es Smalltalk para programadores de C++”. No existen aún, por otro lado, proyectos en Java de la misma gran magnitud que en Smalltalk, ni realmente Java está preparado para este tipo de proyectos, según expresamente reconoce. La verdad es que empiezan a aparecer comparaciones interesadas entre Java y el resto de lenguajes de cierta extensión: Smalltalk, C++, C, Visual Basic, Object Pascal, etc. Las partes afectadas con insuficiente presencia comercial generan, por otro lado, sus propias comparaciones ventajosas (cual es el caso, por ejemplo, de Eiffel, cuya comparación entre C++, Smalltalk, Eiffel y Java puede revisar el lector en la dirección web “http://www.eiffel.com/doc/manuals/technology/oo_comparison/index.html”). Chris Laffra (“http://members.aol.com/laffra”) es el autor de un traductor gratuito de C++ a Java llamado C2J que los forofos de C++ debieran probar. Y esto sin contar el aluvión de documentación de Sun y la ingente cantidad de folletos electrónicos mayormente tendenciosos que supuran fanatismo en favor y en contra de distintos lenguajes contendientes con Java. Lo que se suele obviar en todo esto es que habría que decidir primero hasta que punto Java está maduro como lenguaje de programación para ser comparado con otros, como Smalltalk, con una antiguedad de más de 20 años.

HELLO WORLD

El inevitable ejemplo de saludo ha de servir para explicar algo de lo que Java supone:

// La clase es la unidad operativa de Java, así que todo son clases

class HolaA {

// A continuación se declara y define una función de clase

// (estática: común a todas las instancias de tal clase) con

// acceso público, redefiniendo la función “main” y signifi-

// cando así que la clase puede ser el módulo inicial de una

// aplicación. Aplicamos, a la vez, el paso de argumentos en

// el equivalente a la línea de comandos (en el Mac tal no

// existe en puridad), usando “String” en lugar de “char*”

public static void main( String args[] );

{

System.out.print( “Hola ” );

// Seguidamente se itera por el conjunto de

// argumentos. Hay que notar que en Java el primer

// argumento es el índice cero, mientras que en C++

// tal es el nombre del programa. Quizás la dificultad

// en establecer cuál es en cada caso y plataforma

// tal nombre haya llevado a Java a esta decisión.

for ( int n = 0; n < args.length; n = n + 1 ) {

// Si no hubiéramos chequeado la longitud de la

// lista de argumentos, nos habríamos arriesgado

// a obtener una fea excepción del tipo

// java.lang.ArrayIndexOutOfBoundsException

// que, en cualquier caso, también podríamos

// manejar mediante “try” y “catch”.

System.out.print( args[ n ] );

// A continuación suplimos el espaciado entre

// argumentos, tal y como son introducidos.

System.out.print( “ ” );

}

// Sin la siguiente línea todo el código anterior no

// serviría para nada, pues es la que al mandar al

// dispositivo estándar de salida un retorno de carro

// hace que se imprima el buffer. Esta función puede

// ser también usada con una cadena, naturalmente.

System.out.println();

// Lo que sigue provocaría un error por redefinición

// en C++, mientras que es correcto en Java, donde la

// definición de la variable “n” en la expresión “for”

// posee un ámbito que termina con el bloque “for”.

int n = 1;

}

}

HERRAMIENTAS

El JDK (o Java Developer’s Kit), disponible para Windows 95, NT y Solaris 2.X [3], y de nada inituitiva instalación, consta de diversas y muy rudimentarias herramientas: un compilador un tanto ineficiente (javac), un depurador de línea de comandos de escasa practicidad (jdb), un visor de applets (appletviewer), un desensamblador (javap) que vuelca el contenido de clases compiladas, un generador de cabeceras (javah), un constructor elemental de documentación (javadoc) a partir de comentarios señalados (//* */), el intérprete (java) y las versiones no optimizadas de tales herramientas. Nada, pues, de IDEs, compositores visuales o sutilezas amaneradas.

ÁMBITO INTERNO, ÁMBITO EXTERNO

Como vimos en el ejemplo anterior, una variable declarada y definida en una expresión de control de flujo (“for” en ese caso) posee un ámbito interior al bloque que tal supone. Esto es, si en un “for” se define una variable “n”, ésta no podrá ser utilizada después de terminar el bucle “for”. “Oh, esto parece muy razonable”, exclamará aquí el irreflexivo lector, quejoso de la extensión en C++ de tal ámbito hasta el fin del bloque inmediatamente exterior al bucle. Pero piénsese que en C++ esta facilidad equivale a definir la variable en la línea inmediatamente anterior al bucle, de forma que el estilo de codificación que define todas las variables al principio de un módulo, tan típico en C, se troque más legible. El problema con Java es que tal código no podrá ser reconvertido, pues un acercamiento de la definición de una variable a su primer uso originará errores de compilación si la misma había sido usada tras el bloque. Que una facilidad sintáctica de “decoración” pueda generar errores de compilación (y otros más graves de solapamiento de identificadores) resulta absurdamente lesivo. Naturalmente ninguna de las soluciones es inatacable, pero es precisamente por esto que ninguna de ellas ha de presentarse como exclusiva solución ante la dolosa maldad de la otra.

GOTOS, ETIQUETAS Y EXCEPCIONES

Resulta curioso que Java proporciona las expresiones de control de flujo “break” y “continue” que, seguidas opcionalmente de una etiqueta, significan “gotos” puros y duros, por poner una etiqueta que en este caso no es en absoluto opcional, mientras que la palabra reservada “goto” anda pendiente de definición precisa. Pero si esto no se le antoja lesivo al lector, ¿qué decir de la construcción “finally”, que al término de un bloque de manejadores “catch” asegura que pase lo que pase con el código sujeto al “try”, se genere o no una excepción (manejada o no), un cierto código se ejecutará siempre?: se trata, sin ambages, de un goto incondicional a prueba de excepciones. Naturalmente que podría afirmarse que lo que pretende Java es afianzar su carácter multiparadigma, pero esto resulta especialmente contradictorio con el ánimo de sus diseñadores, que conscientemente han eliminado “sobrecarga de operadores” y “herencia múltiple general”, entre otras características no triviales de extensión lingüística, por considerar que aportaban al lenguaje una complejidad difícil de manejar. Una buena cuestión es si el uso de los “gotos”, expresos o no, se ajusta a este prejuicio contra la complejidad aparente.

MÚLTIPLES FINALES

La palabra reservada “final” es un cualificador de clase que denota que tal clase no podrá tener subclases directas. Se trata, en definitiva, de que cuando se utiliza la expresión “extend”, el compilador comprueba que la clase base no es una clase “final”. Bien, esto resulta claro y legible, aunque el uso de esta característica puede necesitar de lo que un colega llama “el principio de la clarividencia”, pues no sólo de jerarquías de subtipación vive el programador. Lo que no resulta tan claro es la sorprendente reutilización del mismo identificador “final” para indicar que un método no puede ser redefinido (y esto todavía semeja lo anterior), como también para señalar variables que, siendo inicializadas y definidas a la vez, no pueden cambiar su valor (variables constantes, vaya). Parece que con “final” se pretende indicar la inmutabilidad futura de un componente, pero ¿por qué mancillar la pretendida sencillez del lenguaje con tal reutilización? Y es que el término “const” anda pendiente de concreción en Java.

SOBRECARGAS Y LIGEREZAS

Java, tomando como referencia absoluta la sintaxis de C++, aparentemente decide eliminar las sobrecargas de operadores por considerarlas demasiado difíciles de manejar (piense el lector que hacer coexistir constructores, operadores sobrecargados y operadores de conversión sin que sea posible generar situaciones de ambigüedad es en algunos casos imposible y en otros una muy ardua tarea). El lenguaje predefine, sin embargo, una sobrecarga “intuitiva” del operador + para la concatenación de “strings”, y es que precisamente la sobrecarga de operadores sirve, bien usada, para favorecer la legibilidad del código. Así que me resulta un cierto arcaicismo codificar la clase “Complejo” sin usar los mismos operadores que utilizo para operar con “floats”. En C++ la sobrecarga de operadores es una consecuencia más de la decisión de que clases y tipos predefinidos son de la misma categoría, circunstancia que evidentemente no se da en Java.

CADENAS INMUTABLES Y COMPARACIONES ODIOSAS

Java provee la clase “String” para el manejo de cadenas de caracteres, con la particularidad de que los objetos de ese tipo no pueden ser cambiados. Esto es, una variable puede apuntar a una cadena dada (verbigracia: “hola”), pero a través de esa variable la cadena no puede ser cambiada (en Java no existe el equivalente del operador [] para Strings [4]), de forma que lo único que puede hacerse es que la variable apunte a otra cadena distinta:

String cadena = “polímero”;

// A la variable “cadena” se le asigna ahora un nuevo objeto

// String que se crea por concatenación de los cuatro primeros

// caracteres de “polímero” + la cadena “tico”, lo que nos da

// buena idea del origen de algunos de nuestros prohombres.

cadena = cadena.substring( 0, 4 ) + “tico”;

La idea es que se reutilicen las cadenas de caracteres de un modo parecido al idioma de sobre/carta en C++ bien explicitado por Coplien. El lector habrá también advertido, ante estas decisiones, por qué Java ha necesitado sobrecargar el operador + para Strings, ya que todas las funciones deben ser funciones-miembro de alguna clase y otra solución complicaría enormemente la legibilidad del código.

Resulta así que una cadena será independiente de las variables que la “apunten”, por lo que parece que las operaciones con Strings mantendrán un esquema semántico basado en el valor de las cadenas apuntadas. Desafortunadamente la coherencia no se mantiene respecto del operador de comparación:

cadena.substring( 0, 8 ) == “político”; // falso

cadena.substring( 0, 3 ) == “pol”; // falso

cadena == “político”; // verdadero

pues éste verifica la igualdad de los objetos implicados (su identidad referencial) en lugar de comparar el valor de la cadena en cada caso referenciada. Ciertamente se trata de una mezcolanza de difícil explicación y sorprendente comportamiento.

ESTRATEGIA CÓSMICA

Siguiendo el tentador ejemplo de Smalltalk, todas las clases en Java son extensiones, directas o no, de la clase Object. También al igual que en Smalltalk, las variables son punteros no visibles (no manejables directamente) con semántica de referencias. Se trata, pues, de un lenguaje monoparadigmático, que obliga a una programación forzada a la derivación de clases. Como por otro lado Java no cuenta con tipos parametrizables (las plantillas de C++, soporte de la muy efectiva y elegante Standard Template Library), todos sus contenedores admiten derivados de Object, de forma que para recuperar un determinado elemento hay que aplicar un “cast” que será validado en tiempo de ejecución. La recolección automática de basura ayuda, afortunadamente, a superar algunos de los problemas de gestión de memoria que se notan en mi anterior artículo “Contenedores y Plantillas en C++”. El problema es que el estilo de codificacion Smalltalk es preferible precisamente embebido en un entorno Smalltalk, que fue diseñado a tal fin con precisión.

DESTRUCTORES OCASIONALES

Los constructores son muy parecidos a los de C++, con la particularidad que Java asegura la inicialización de todas las variables, expresamente codificadas o no, anteponiendo la seguridad a la eficiencia. Al contar con recolector automático de basura (o de residuos), no se da la necesidad de codificar destructores. Sin embargo Java procura una función miembro de destrucción con signatura “void finalize()” en cuyo interior pueden codificarse rutinas de desasignación y limpieza. El problema es que Java no garantiza que tal método vaya a ser finalmente llamado, de forma que ninguna porcion de código debiera depender del mismo. Si se observa, por otro lado, como una posible optimización, el impacto real en la aplicación será, cuando menos, impredecible. Lo cierto es que no conozco ejemplos concretos de uso adecuado de esta palabra clave, así que habrá que esperar a la experiencia.

MODELO-VISTA-CONTROLADOR

¿Qué pasa con el MVC [5]? ¿Hay que reinventarlo para Java? Bueno, el lenguaje provee algunas clases como “Observer” y “Observable” que pudieran parecer suficientes para soportar el estilo de programación MVC. El problema es que Smalltalk dispone de un método que hace corresponder un String con una llamada a un método en tiempo de ejecución:

object perform: #method

mientras que en Java no existen estructuras de tipo diccionario que contengan los métodos, como en Smalltalk, de forma que al faltar las capacidades de metainterpretación el esquema MVC no puede hacerse funcionar. Naturalmente una solución (insoportablemente tediosa pero finalmente funcional) sería pasar como argumentos objetos cuyo sólo propósito fuera permitir la invocación de un único método.

AWT

Éste es el acrónimo de X Window Toolkit, donde X puede ser Abstract, Alternative, Awkward o Another, aunque finalmente Sun está promoviendo la abstracción (seriedad ante todo). Bueno, en breve se trata de una biblioteca de clases Java para el desarrollo de interfaces gráficos de usuario. En el momento de escribir este artículo la versión 1.0 del AWT, que se desarrolló en sólo dos meses (de octubre a diciembre de 1.995), es la parte más débil del conjunto que representa Java como lenguaje: no sólo no se han tenido en cuenta las ideas de entornos gráficos novedosos (como Fresco), sino que se ha ahondado (y la presión del time-to-market ha tenido mucho que ver) en estructuraciones dolosas orientadas-a-eventos, plenas de callbacks y sin ningún soporte del entorno para la construcción gráfica. Amy Fowler, jefa del proyecto AWT en Javasoft, que actualmente consta de 6,5 personas (cosas de la informática), ha asegurado, sin embargo, que todo esto pronto pertenecerá al pasado, y el AWT será multi-idioma (en la actual versión los recursos no se almacenan externamente), constará de herramientas visuales, etc. En fin, seguro que el futuro nos depara muchas sorpresas, suelen amenazar los astrólogos. En tanto, he aquí la versión revisitada de nuestro saludo electrónico:

// La siguiente expresión se encuentra entre un “#include” y un

// “namespace” de C++ (en esencia, claro, pues se trata de un

// cualificador no-exclusivo de ámbito). De esta manera cuando

// escribimos Frame nos ahorramos escribir java.awt.Frame.

import java.awt.*

// Nuestra clase desciende de la clase base “Frame”

public class HolaPolitico extends Frame {

// sigue un constructor público, que establece el tamaño,

// el tipo de letra, el fondo y el título de la ventana,

// para finalmente mostrarla en pantalla.

public HolaPolitico()

{

setFont( new Font( “TimesRoman”, Font.BOLD, 18 ) );

setBackground( Color.white );

setTitle( “Un Hola Politizado” );

resize( 300, 200 );

show();

}

// Hay que controlar el evento que finiquita nuestra ventana

public boolean handleEvent( Event e )

{

if ( e.id == Event.WINDOW_DESTROY )

System.exit( 0 );

return false;

}

// Para dibujar cualquier cosa se redefine el método paint

public void paint( Graphics g )

{

g.setColor( Color.blue );

g.drawString( “Yo a usted no le conozco”, 50, 50 );

}

// Y por último la función principal

public static void main( String args[] )

{

new HolaPolitico();

}

}

Claro que ejemplo tan sencillo poco puede ilustrar. En realidad la estructura básica del AWT se basa en Componentes y Contenedores. Estos últimos contienen componentes posicionados a su respecto y son componentes a su vez (recuerde el lector la estructura de glyphs típica de los procesadores de texto), de forma que los eventos pueden tratarse tanto en contenedores como en componentes (siempre mediante la herencia, claro), corriendo por cuenta del programador (pues aún no existen herramientas de composición visual) el encaje entre todas las piezas, así como la seguridad de tratamiento de los eventos adecuados. En fin, nada trivial.

REFERENCIAS

El lector podrá encontrar en internet papeles, índices, métodos, referencias e incluso manuales completos, libros en pre-edición y comentarios diversos a los distintos aspectos del lenguaje/entorno Java. Lo que ocurre es que la naturaleza volátil de internet sigue aconsejando fiar el conocimiento de la seguridad de las hojas impresas. He aquí algunas de ellas:

  • Hooked on Java: Creating Hot Web Sites with Java Applets , por Arthur van Hoff, Sami Shaio y Orca Starbuck, 1995, Addison-Wesley, 0-201-48837-X, con CD-ROM.
  • Los autores, miembros del equipo de desarrollo de Java en Sun Microsistems Inc., exponen en este texto la euforia de un proyecto con una liviandad que causa escalofríos. Mi pronta reacción a la primera lectura del libro fue la de decepción clara: mucho web, muchos applets, mucha euforia, pero poco lenguaje y demasiadas decisiones de diseño tomadas muy a la ligera, como porque sí. Van Hoff es el autor del compilador Java e impulsor de Hot Java, mientras que Shaio diseñó e implementó el conjunto de herramientas de interfaz de usuario (a la vez que el mecanismo de seguridad de los applets) y Starbuck básicamente se ocupó de la documentación. El libro a menudo refleja la vivacidad de Duke, la mascota Java, y semeja una versión descafeinada de Ecce Homo: “¿Por qué soy tan inteligente?”, “¿Por qué escribo tan buenos libros?”, “¿Por qué soy un destino?” [6]. Con todo el texto se deja leer y querer, como un buen pasatiempo, pues dedica su mayor parte a la descripción de applets y de páginas web. El CD-ROM que lo acompaña incluye todos estos applets, código y páginas web de ejemplo y el JDK para Windows 95/NT y Solaris 2.X. Así resulta que el libro es totalmente recomendable, pues frente a la tontería de los muchos artículos que inmisericordes ya se han publicado, la ligereza exenta de errores y las opiniones de primera mano finalmente resultan un buen plato. Si no le interesa Internet, lo mejor será, por otro lado, que olvide Java.
  • Mecklermedia’s Official Internet World 60 Minute Guide to Java , por Ed Tittel y Mark Gaither, 1995, IDG Books, 1-56884-711-4.
  • Este texto es exactamente lo que anuncia: una guia que se pretende tan supuestamente fácil como el lenguaje que describe. La verdad es que el enfoque sintético favorece enormemente la comprensibilidad y el lector puede acceder a información práctica librándose de bastante basura literaria. Así, en 253 páginas, los autores describen las características básicas del entorno Java, del lenguaje en sí y de los applets, para pasar a examinar con más detalle estos últimos en el contexto de internet/html, y después exponer varias técnicas de codificación de aplicaciones Java (incluido el ejemplo de un manejador de protocolos) y hablar de su futuro. La descripción de la gramática de Java y del API que conforman lenguaje, bibliotecas y Hot Java terminan de redondear el texto. Naturalmente el libro no enseña a programar, sino que más bien muestra ordenadamente lo que finalmente hay (muchos adverbios). En fin, que lo más agradable del texto es su carencia de pretensiones.
  • Java! , por Tim Ritchey, 1995, New Riders Publishing, 1-556205-533-X.
  • Se trata aquí de una descripción del lenguaje/entorno Java con un claro tono pedagógico para programadores y administradores de sistemas. Así que tras la típica introducción, se establecen procedimientos de instalación del software, de variables de entorno, etc., para después pasar a una revisión de tipos, expresiones, estructuras de control, clases, interfaces, paquetes, hilos, excepciones, bibliotecas de clases, AWT, Internet (¿cómo no?), y dos interesantes secciones sobre el interfaz con C y la máquina virtual Java. Sin duda el libro complementa los dos anteriores.

[1] Seguro que el leído lector sabe que el antiguo término castellano “(h)uebos” significa “necesidad”. Por webos vendría a querer decir, así, “por e-necesidad”.

[2] El diminutivo no encierra ningún ánimo despectivo, sino más bien práctico: ¿Imagina el lector un applet del tamaño de WinWord con las actuales conexiones a Internet mediante una conexión telefónica a 9.600 bps o aún a 28.800 bps?

[3] IBM ya dispone de sus propias versiones del JDK para AIX (1.01) y OS/2 Warp (1.0), ambas producidas en base a un acuerdo del 6-12-95 con Sun Microsystems Inc.

[4] Para cambiar caracteres individuales Java proporciona la clase “StringBuffer”, de parecida funcionalidad y nombre autoexplicativo.

[5] MVC (Model-View-Controller) es un esquema/patrón soporte de interfaces gráficos desarrollado por Trygve Reenskaug y Adele Goldberg y embebido en la arquitectura del lenguaje Smalltalk.

[6] Recapacite el lector que Nietzsche admiró profundamente a Wagner antes de denostarlo por su decadencia insoportable, así que la comparación musical con el C++ quizás no resulte desafortunada.

 
     
 
 
volver a la página de publicaciones
 
 
 Pº. Castellana 188, 14º e · 28046 - Madrid · info@a4devis.com