El Lenguaje de Programación Java Jorge Salinas E. 13 de abril de 2004
Índice general 1. Generalidades de Java 2 1.1. Variables............................... 3 1.2. Comentarios y Constantes...................... 4 1.3. Clases y Objetos........................... 4 1.4. Constructores............................. 5 1.5. Campos estáticos o de clase..................... 6 1.6. El Recolector de Basura....................... 7 1.7. Un método más útil......................... 7 1.8. Arreglos................................ 7 1.9. Herencia................................ 8 1.10. Excepciones.............................. 9 1.11. Colecciones.............................. 10 1.12. Ant.................................. 11 1.12.1. Proyectos........................... 11 1.12.2. Targets............................ 11 1.12.3. Propiedades.......................... 12 1.13. Conclusiones............................. 13 1
Capítulo 1 Generalidades de Java Java es un lenguaje de Programación Orientado a Objetos, los programas Java se hacen con clases, a partir de una denición de clase se puede crear una cantidad enorme de Objetos que también se conocen como instancias de una clase. Es muy útil pensar en una clase como una fábrica de objetos con planos e instrucciones para construir algún dispositivo, los objetos en este caso serían los dispositivos hechos por la fábrica. Una clase contiene dos tipos de elementos, los campos (también llamadas propiedades) y los métodos (también llamadas operaciones). Los campos son datos de la clase y componen algún estado del objeto. Los métodos son funciones que operan sobre los campos para manipular el estado de un objeto. Veamos como sería el Hola Mundo en Java. class HolaMundo { public static void main(string[] args) { System.out.println("Hola, Lenguajes de Programacion"); Escriba este código en su editor favorito (Asumiendo que se está utilizando Linux) que probablemente sería el vi(1). Llame al archivo HolaMundo.java y asegurese de que el archivo esté dentro del classpath 1. Luego debe compilar el archivo con javac(1). Para ejecutarlo debe ingresar en la línea de comandos $java HolaMundo. Cabe señalar que Java es sensible a las mayúsculas y minúsculas. Si todo está en orden debería aparecer en la consola Hola, Lenguajes de Programación. El compilador javac compila el código ByteCode que es código que entiende la màquina virtual Java (El código máquina de la máquina virtual). 1 El Classpath es el path físico en donde java busca las clases para su ejecución. Deben agregar su directorio de trabajo a la variable de ambiente CLASSPATH. Suponiendo que se usa BASH, deben hacerlo o bien con export o agregándolo a su.bashrc o.bash_prole 2
Cuando se declara un método main en la clase, esa será la que se ejecutará cuando llamemos a la clase desde java. Nótese que el método debe ser tanto public como static, esto se verá más adelante. Por tanto void signica que el método no devuelve nada. El método println de la clase out es el que escribe por la salida estándar. 1.1. Variables Para explicar las variables se usará el ejemplo de la serie de Fibonacci, cuyo n-ésimo elemento es la suma de los dos anteriores. public class Fibonacci { public static void main(string[] args){ int primero = 1; int segundo = 1; System.out.println(primero); while (segundo < 50){ System.out.println(segundo); segundo = primero + segundo; primero = segundo - primero; En el ejemplo se usan variables de tipo entero de 32 bits con signo cuyos valores están en el rango de 2 31 a 2 31 1. Java tiene incorporado tipos de dato primitivos. Los tipos de datos primitivos de Java son los siguientes: boolean. true o false char. Carácter Unicode 1.1 de 16 bits. 2 byte. Entero de 8 bits (con signo). short. Entero de 16 bits (con signo). int. Entero de 32 bits (con signo). long. Entero de 64 bits (con signo). float. Coma otante de 32 bits. (IEEE 754-1985) double. Coma otante de 64 bits. (IEEE 754-1985) 2 El código fuente tambien es Unicode, esto signica en terminos simples, que se pueden declarar variables como double π = 3.14; 3
1.2. Comentarios y Constantes Los comentarios en Java son iguales que en C/C++ es decir se puede usar // y /* */. Para declarar constantes se debe usar la palabra reservada final, que después se puede usar para que una clase no se pueda heredar. 1.3. Clases y Objetos Java como cualquier lenguaje de programación orientado a objetos, proporciona una herramienta para resolver problemas de programación usando la noción de clase y objeto. En Java los objetos tienen un Tipo, ese tipo es la clase del objeto. Como se había mencionado antes, una clase tiene dos elementos, campos y métodos. Los campos son variables de datos (o objetos) asociados con una clase y sus objetos. Los campos almacenan los resultados de los cálculos realizados por los métodos de la clase. Los métodos contienen el código ejecutable de una clase. Los métodos se crean a partir de sentencias Java. La forma en que se invocan los métodos determina la ejecución del programa. Por ejemplo creemos una clase que represente un punto en el espacio 3D. public class Punto { private double x,y; public double getx(){ return x public double gety(){ return y public void setx(double mix){this.x=mix; public void sety(double miy){this.y=miy; public String tostring(){return "(" + x + "," + y + ")" Con esta clase podemos crear objetos Punto en otro programa, digamos: Punto mipunto = new Punto(); mipunto.setx(0); mipunto.sety(1); System.out.println(mipunto.toString); El programa lanzará en la salida estandar (0,1). Detengámosnos un poco para analizar los programas, la clase Punto tiene dos campos privados (no se puede acceder a x e y directamente salvo con métodos), los métodos creados son setx, sety, getx y gety. Los nombres de los métodos son explicativos, los set setean los campos y los get obtienen los campos. El método tostring retorna una representación del objeto como String. 4
Si el usuario intentáse acceder a x o a y de algún objeto directamente (mipunto.x = 3 por ejemplo) no podrá y Java lanzará una Excepcion de acceso ilegal, para acceder a los miembros privados de una clase solo se puede lograr mediante los métodos. Para crear un objeto se debe usar la palabra reservada new, lo que hace new es llamar al Constructor de la clase, que es un método especial pues su función es inicializar el objeto. En la siguiente sección se introducen los constructores. 1.4. Constructores Un Constructor es un método que lleva el mismo nombre de la clase y su objetivo es inicializar el objeto creado, o bien reservar espacio para su utilización. En el ejemplo anterior no se denió ningún constructor, pues si no existe un constructor Java crea uno propio. Un constructor puede tener o no tener parametros y podemos crear cuantos queramos (polimorsmo). Ejemplos de constructores para la clase Punto son los siguientes. public Punto(){ //Este Constructor Inicializa X e Y con 0 this.x=0; this.y=0; public Punto(double mix, double miy){ this.x=mix; this.y=miy; public Punto(Punto mipunto){ this.x=mipunto.getx(); this.y=mipunto.gety(); A proposito de this, es una referencia al objeto mismo, al decir this.x hago referencia al x del objeto en cuestión. Entonces para la creación de un objeto de la clase Punto, nos queda invocar algún constructor. Punto mipunto = new Punto(); Punto mipunto = new Punto(1,2); Punto mipunto = new Punto(new Punto(3,4)); //Esto es válido 5
1.5. Campos estáticos o de clase Ya nos hemos encontrado con la palabra clave static. A veces puede ser necesario tener una variable compartida para todas las instancias de una clase o tener un método en alguna clase que se pueda llamar sin tener que inicializar un objeto de esa clase para llamarla (es un poco violar la orientación a objetos, pero está permitido). Cuando una variable es compartida por todas los objetos de esa clase se le denomina variable de clase. Al denir un campo como static, el valor será visto por todas las instancias de esa clase y servirá como un método para compartir una variable. En el caso de llamar un método sin llamar a su constructor, ya hemos visto algunos ejemplos, como System.out.println, nótese que estamos haciendo una referencia absoluta en donde se encuentra el método println. Esta se encuentra en una clase llamada System que tiene un campo llamado out que tiene un método para escribir por la salida estándar (println). Cabe señalar que los métodos estáticos no pueden acceder a las variables de la clase (salvo que sean estáticas) pues no tiene referencia a un objeto. A medida que se familiarizen con Java, aprenderan a usar varios métodos estáticos bastante útiles. Por ejemplo en la clase Integer hay un método estático llamado parseint que recibe un String y lo transforma a int 3. Veamos un ejemplo no muy útil, pero que muestra la idea de un método estático en alguna clase. public class Prueba{ private int x; public Prueba(){ this.x=0 public static void ImprimePrueba(){ System.out.println("Esta es una Prueba"); public int getx(){ return this.x; Prueba.ImprimePrueba(); //Ningún Problema Prueba.getX(); //Mal Prueba miprueba = new Prueba(); 3 También notarán que existe una clase Integer que no es lo mismo que el tipo de dato int. La clase Integer tiene muchos métodos útiles y engloba de cierta forma al tipo primitivo int 6
miprueba.getx(); //Correcto 1.6. El Recolector de Basura Después de crear un objeto usando new, como lo hacemos para liberar la memoria usada por el cuando ya no se usará más. (delete en C++) Lo único que se debe hacer es no usarlo más, porque Java tiene un mecanismo llamado el Recolector de Basura, que se encarga precisamente de liberar el espacio usado por objetos que ya no son referenciados. 1.7. Un método más útil En nuesta clase punto crearemos un método para calcular la Distancia Euclideana entre dos puntos (hypot en C/C++), usaremos dos métodos estáticos de la clase Math llamados sqrt y pow. El método de la clase Punto sería de esta forma: public double distancia(punto otropunto){ double diferenciax, diferenciay; diferenciax = this.x - otropunto.getx(); diferenciay= this.y - otropunto.gety(); return Math.sqrt(Math.pow(diferenciaX,2) + Math.pow(diferenciaY,2)); Punto mipunto = new Punto(); //Origen Punto miotropunto = new Punto(2,1);//(2,1) double midistancia = miotropunto.distancia(mipunto); double midistancia = mipunto.distancia(miotropunto); Las dos formas entregan el mismo resultado. 1.8. Arreglos Un arreglo es una colección de variables, todas del mismo tipo. La longitud de un arreglo se asigna al crear el arreglo y no se puede cambiar nunca. Veamos un ejemplo: class Baraja { final int TAMANO_BARAJA=52; 7
Carta[] miscartas = new Carta[TAMANO_BARAJA]; public void print() { for (int i=0; i< miscartas.length; i++) System.out.println(cartas[i]); Los límites del arreglo van desde 0 a arreglo.lenght - 1. Si se usa un índice que está fuera de los límites del arreglo, Java lanzará una Excepción IndexOutOfBoundsException. 1.9. Herencia Una de las principales ventajas de la orientación a objetos es la capacidad de heredar o extender el comportamiento de una clase existente, es decir crear subclases y seguir usando el código escrito en la clase original. Cuando una clase se extiende para crear una nueva, la nueva clase extendida hereda los campos y métodos de la clase que ha sido extendida. La clase original en que se base la extensión se conoce como superclase. Veamos a continuación un ejemplo de herencia en Java: class Pixel extends Punto { private Color color; public void clear() { this.x=0; this.y=0; color=null; La clase Pixel extiende el comportamiento tanto de los datos como de los métodos de Punto. Además se crea un campo adicional llamado color. También se pueden sobrecargar métodos que existían en la superclase pero para la subclase se desea que se comporte distinto, una buena idea es sobrecargar el método tostring. public String tostring(){ return super.tostring() + " " + color.tostring; //Suponiendo que la clase Color tiene un método tostring 8
1.10. Excepciones Una Excepción es un evento que ocurre durante la ejecución de un programa que cambia el ujo normal de las instrucciones. Veamos un ejemplo: public class test { public static void main(string[] args) { int temp[] = new int[3]; temp[3] = 4;... Al ejecutar javac desde la línea de comando no habrá problema, sin embargo al ejecutar java: aragorn$ java test Exception in thread ``main'' java.lang.arrayindexoutofboundsexception at test.main(test.java:4) Las Excepciones proporcionan una manera limpia de vericar errores sin complicar el código. Se lanza una excepción cuando se encuentra una situación imprevista de error. La Excepción es capturada entonces por una cláusula situada más arriba en la pila de invocación al método. Si la excepción no es capturada interviene un manejador de excepciones por defecto, que habitualmente imprime información útil sobre dónde se ha lanzado la excepción. Para lanzar una excepción se usa la palabra clave throw que toma un objeto como parámetro. Veamos un ejemplo de como lanzar una Excepción. public Test() throws Exception { Clase miobjeto = new Clase(); if (miobjeto == null) throw new Exception("No Se Pudo Crear El Objeto") La clausula throws permite denir que Excepciones podría lanzar el método. Para capturar una Excepción se hace con un bloque Try/Catch/Finally. Si una sección crítica de código puede fallar por alguna circunstancia es recomendable encerrarlo por un bloque try/catch. Por ejemplo: try{... 9
// Intento acceder System.out.println(a[n]);... catch(indexoutofboundexception e) { //Capturo la Excepcion System.out.println(e.toString()); System.exit(1); Finally{ //Pase Sin Problemas Si se programa sin manejar las Excepciones Java lo hará, pero es muy recomendable para la conabilidad del programa y para tener los errores controlados. Para más información de Excepciones, ver la página Web. 1.11. Colecciones Java ofrece un sin número de clases, entre ellas están las Colecciones que las dene la interfaz Collection, las más conocidas implementaciones son Vector, ArrayList, LinkedList. Una colección permite agregar, eliminar, buscar, etc. elementos en una lista. Por ejemplo, si quisieramos (por esas extrañas razones de la vida) tener una Encuesta con varias Preguntas, se podría implementar algo así: public class Encuesta{ private String titulo; private ArrayList preguntas; public Encuesta(String mititulo){ titulo = mititulo; preguntas = new ArrayList(); public void agregarpregunta(pregunta mipregunta){ preguntas.add(mipregunta); public void borrarpregunta(pregunta lapregunta){ if preguntas.contains(lapregunta) preguntas.remove(lapregunta); 10
Y así solamente usando add y remove puedo agregar y eliminar elementos de la lista. Las colecciones tienen varios constructores, uno le puede especicar la tasa de crecimiento (pues crece dinámicamente) y varias otras cosas. Solamente es cosa que usen el Javadoc. 1.12. Ant Ant es una herramienta hecha para constuir (build) programas en java. Es como el Make, pero no tan engorroso. Para instalar ant en un sistema operativo Linux se debe hacer lo siguiente: 1.- Obtener la última versión estable de Ant en http://apache.intissite.com/ant/binaries/apacheant-1.6.1-bin.tar.gz 2.- Descomprimir el Archivo. (/usr/local/ant ) 3.- Agregar el directorio bin al path. 4.- Se deben agregar las siguientes variables de entorno: export ANT_HOME=/usr/local/ant export JAVA_HOME=<PATH DE java (sin el /bin)> export PATH=${PATH:${ANT_HOME/bin La ultima es para el path. Es recomendable que se haga en /etc/prole y luego umask 022. Los archivos para construir un programa en Java son archivos Xml que contiene un project que tiene por lo menos un (por defecto) Target. Los targets tienen tareas o task. 1.12.1. Proyectos Los proyectos tienen tres atributos: Atributo Descripcion Requerido name El nombre del proyecto No default El Target por defecto Si basedir El directorio base para el cual todos los calculos de path se harán. No 1.12.2. Targets Un Target puede depender de otro. Se puede tener un target para compilar por ejemplo, otro para limpiar, uno para generar un.jar, etc. El atributo depends dice que se debe ejecutar otro target primero que este. Por ejemplo: <target name=a> <target name=b depends=a> <target name=c depends=b> <target name=d depends=c,b,a> 11
1.12.3. Propiedades Las propiedades tienen un nombre y un valor, son como constantes, para hacer referencias a ellas se deben llamar con ${NombreConstante Un task es un trozo de código que se ejecuta. Pueden tener multiples atributos. Mejor veamos un ejemplo: <project basedir="." default="run"> <description></description> <property name="src.dir" value="src"/> <property name="classes.dir" value="classes"/> <property name="lib.file" value="frameencuesta.jar"/> <property name="classpath" value="${classes.dir:${lib.file"/> <property name="main.class" value="mainencuesta"/> <target name="prepare" description="prepares the project folders"> <echo message="creando directorio destino para archivos compilados"/> <mkdir dir="${classes.dir"/> </target> <target name="compile" description="compiles java files." depends="prepare"> <echo message="compilando archivo fuente y generando bytecode"/> <javac srcdir="${src.dir" destdir="${classes.dir" classpath="${classpath" debu </target> <target name="run" depends="compile"> <echo message="ejecutando clase principal"/> <java classname="${main.class" fork="true" classpath="${classpath"> </java> </target> </project> Se empieza con un proyecto que pone como directorio base al directorio actual (.) y que por defecto se llamará al target run. Luego se ponen propiedades, por ejemplo hay propiedades que guardan en si algunos directorios. La propiedad src.dir tiene como valor el string src que dice en el fondo que dentro del directorio actual hay un directorio llamado src (que contiene los archivos fuente). Hay otra propiedad para poner el nombre del directorio donde se guardaran los ejecutables. Hay 2 propiedades mas que denen un archivo.jar que contiene todas las clases de la interfaz graca. La propiedad del classpath nos permite agregar este jar al classpath para que se pueda ejecutar nuestra interfaz graca. 12
Hay 3 targets, uno que prepara (para crear la estructura de directorios), otro que compila, y otro que corre la aplicación. Para ejecutar un target en especico se debe llamar a ant en la consola seguido del target que se desee ejecutar. Por ejemplo para compilar se debería hacer: localhost$ant compile Agreguen al build.xml de su tarea el siguiente target: <target name="clean" description="limpia" > <echo message="limpiando..."/> <delete dir="${classes"/> </target> Y usenlo para limpiar su tarea. Ojo que para su tarea tienen que modicar la propiedad main.class que la reemplazarán por una hecha por ustedes. Por ejemplo: <property name="main.class" value="tarea2"/> Para mayor información (y si que hay harta) busquen en http://ant.apache.org/manual/index.html 1.13. Conclusiones Este texto intenta aproximar a los alumnos de Lenguajes de Programación hacie el mundo Java, lo que se mencionó acá es una breve pincelada de cada tema. Se recomienda hacer un buen uso del javadoc pues es de las mejores ayudas que ofrece un lenguaje de programación. Cabe señalar que gran parte de este breve tutorial esta sacado del libro El Lenguaje de Programación Java de Ken Arnold y James Gosling. Consultas a aragorn@labsd.inf.utfsm.cl JSE /LATEX 13