Examen de Programación (13294) Convocatoria de Junio 2008 Licenciatura de Lingüística y Nuevas Tecnologías Pregunta 1 a) Explicar qué es un NullPointerException ( por qué ocurre? cuando se produce?). Dar un ejemplo de código donde se puede producir este tipo de problema. Un NullPointerException es un error que ocurre a la ejecución. Se produce cuando intentamos acceder a las variables o métodos de un objeto con una variable de objeto que no apunta a ningun objeto (referencia nula). Por ejemplo: String cadena=null; if (cadena.length()>0) System.out.println( YES! ); La variable de objeto cadena no apunta a ningun objeto, y al llamar al método length() del objeto de tipo String se produce una excepción de tipo NullPointerException. b) Explicar qué es un ArrayIndexOutOfBoundException ( por qué ocurre? cuando se produce?). Dar un ejemplo de código donde se puede producir este tipo de problema. Un ArrayIndexOutOfBoundException es un error que ocurre a la ejecución. Se produce cuando intentamos acceder a un elemento dentro de un array usando un índice que está fuera del rango de índices de este array. Por ejemplo: String[ ] cadenas = { A, B, C ; cadenas[3] = D ; Con la segunda instrucción intentamos acceder al cuarto elemento del array (índice 3), y este array solo contiene 3 elementos. c) Explicar qué es un BreakPoint en Netbeans y para qué sirve. Un BreakPoint sirve a la hora de depurar un programa (hacer debugging). Se pone en cualquiera línea de código de un programa y al ejecutar el programa en modo debugging, se puede acceder directamente a esta línea de código, sea donde sea, saltandose todas las instrucciones anteriores. Sirve por si nos interesa mirar la ejecución del código a partir de algun punto en particular.
Pregunta 2 a) Para cada uno de estos trozos de código, decir si es correcto () o incorrecto (). Un código incorrecto no compila mientras que un código correcto puede compilar (dado una compleción correcta de la clase), independientemente de si hace algo relevante o no. String st = new StringTokenizer( hello, how are you? ); Word word = new Word( el ); System.out.println(word); int i = new Integer(3); String cadena = hola ; cadena = replaceirst( h, H ); Morpho morpho = new Morpho( el, Det ); Word word = morpho; b) Explicar por qué, para comparar dos objetos, no sirve el operador de igualdad ==. El operador de igualdad sirve para comparar variables de tipo básico como int o char. Si lo usamos para intentar comparar dos objetos, entonces lo que se comparará serán las referencias (contenidas en las variables de objetos) y no los objetos (a los que apuntan las variables de objetos). Para comparar dos objetos tenemos que usar métodos especificos, como equal() en el caso de String. c) Explicar como funciona el sistema de referencias por atrás (back references = $1,$2, etc.) en el método replaceirst de String. Dar un ejemplo de uso, sabiendo que la firma de este método es: String replaceirst(string expresionregular,string cadenadesustitucion). Las subcadenas que queremos sacar de nuestra cadena las ponemos entre parentesis dentro de la expresión regular (primer argumento de replaceirst). Cada par de parentesis corresponde a una referencia por atrás: el primer par corresponde a $1, el segundo par a $2, etc. Por ejemplo: String cadena = 10:30 ; cadena = cadena.replaceirst( (.+):(.+), $1$2 ); El $1 corresponde al primer par de parentesis (.+) es decir 10, y el $2 al segundo par (.+) es decir 30. Con este replaceirst, sustituimos 10:30 por 1030.
Pregunta 3 Decir para cada una de estas afirmaciones si es erdadera () o alsa (). 1,5 punto 1. Los métodos del paquete TextIO son métodos de instancia. 2. Un método definido como static es un método que solo se puede llamar dentro de la misma clase en la que está definido. 3. Un paquete (package) define un conjunto de métodos. 4. Una variable de instancia no puede ser de tipo básico. 5. Una clase puede tener más de un constructor. 6. Solo se puede crear un objeto por clase 7. Un constructor siempre devuelve la referencia de un objeto 8. Una API es un entorno para desarollar programas escritos en Java mucho más potente que un editor como Scintilla Scite. 9. Una clase siempre tiene que contener el método: public static void main(string[ ] args) 10. Un método que devuelve un valor tiene que contener una(s) instrucción(es) return. Pregunta 4 a) Explicar qué es un BufferedReader. Un BufferedReader es un flujo de caracteres caracterizado por el hecho que permite leer líneas enteras con su método readline(). b) Explicar de manera general qué hace este trozo de programa. InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); String line = br.readline(); br.close(); isr.close(); Este programa lee una línea entrada por el usuario desde el flujo de entrada estándar (es decir desde el teclado). c) Escribir el código que coge dos palabras como argumento de la línea de comandos y los imprime a la pantalla. El código tiene que averiguar antes de usarlos que el usuario ha entrado los dos argumentos. 0,25 punto public static void main(string[] args) { if (args.length < 2) { System.out.println( The program needs two arguments! ); System.exit(0); System.out.println( Has entrado: + args[0] + y + args[1]);
d) Mostrar como se ejecuta este código (la clase se llama P4) desde la ventana cmd, entrando los dos argumentos. Redirigir el flujo de salida estándar a un fichero. 0,25 punto java P4 hello hola > C:\P4.txt Pregunta 5 a) Para cada uno de estos trozos de código, decir si es correcto () o incorrecto (). Un código incorrecto no compila mientras que un código correcto puede compilar (dado una compleción correcta de la clase), independientemente de si hace algo relevante o no. String[ ] array = new String[2]; array[2] = hola ; int i = array[0].length() + 1; array[0] = new Integer(2); array[1] = array[0]; array[0] = hello ; array[1] = 2; String[ ] array = { hello ; b) Qué imprime el siguiente código? int[ ] notas = new int[4]; notas[0] = 0; notas[1] = 10; for (int i=0;i< notas.length;i++) { System.out.println(notas[i]); Imprime: 0 10 0 0 c) Explicar (de forma general, sin reescribir el código) como se tendria que reescribir el código para que se impriman solo las notas asignadas. El problema es que se imprimen elementos del array al que no le han sido asignados ningun valor. Pero el valor por defecto de una variable de tipo int es 0, o sea que no se distingue entre un 0 que es el valor asignado y un 0 que es el valor por defecto. Para que se impriman solo los valores asignados, tendriamos que usar un array de objetos, por ejemplo de Integer, y averiguar que cada elemento no es null antes de imprimirlo.
Pregunta 6 a) Reescribir el código de la pregunta 5b anterior con un ArrayList. Los métodos/constructores relevantes de ArrayList son: ArrayList() add(object obj) int size( ) Object get(int index) Constructor de arraylist Método de ArrayList. Añade un objeto al final del arraylist. Método de ArrayList. Devuelve el tamaño actual del ArrayList Método de ArrayList. Devuelve el objeto dentro del ArrayList a la posición index. ArrayList notas = new ArrayList(); notas.add(new Integer(0)); notas.add(new integer(10)); for (int i=0;i< notas.size();i++) { System.out.println(notas.get(i).intalue()); b) Explicar las tres diferencias principales entre un array estático y un array dinámico en Java. 1) Un array estático tiene un tamaño fijo a su creación que es su tamaño máximo que no puede cambiar. Un array dinámico, a su creación, tiene un tamaño cero, que se va incrementando (o decrementando) cada vez que añadimos (o eliminamos) un elemento. 2) Un array estático puede contener elementos de tipo básico o de tipo objeto mientras que un array dinámico solo puede contener elementos de tipo objeto. 3) Un array estático solo puede contener elementos de un mismo tipo, declarado a la declaración de la variable de tipo array, mientras que un array dinámico puede contener objetos de cualquier tipo, mientras sean objetos. c) Para cada una de estas afirmaciones sobre HashMap decir si es erdadera () o alsa (). Las claves son únicas. Una misma clave puede tener más de un valor. Se recorre el HashMap recorriendo la lista de claves con un Iterator. La clave tiene que ser de tipo objeto pero el valor puede ser de tipo básico u objeto. A la creación del objeto de tipo HashMap, su tamaño es uno.
Pregunta 7 a) Para cada una de estas afirmaciones sobre conceptos de programación orientada a objetos decir si es erdadera () o alsa (). Si tenemos dos métodos en una clase con el mismo nombre pero el tipo del argumento de entrada es diferente, entonces esto se llama overriding (redefinición de métodos) Se pueden instanciar objetos de una clase abstracta Un método abstracto no se puede llamar desde fuera de la clase donde esta definido Cualquiera clase de Java menos la clase Object hereda de alguna otra clase La palabra reservada extends se usa para decir que una clase hereda de otra. b) En la última práctica de la asignatura, llamamos al método imprimir() de manera polimórfica. Explicar qué quiere decir esto y como se realizan estas llamadas. En la última práctica todas las subclases de Morpho, es decir Det, erb, Nom, Adj, etc, definen un método imprimir() que imprime el lema, la categoría y los rasgos morfológicos relevantes para cada categoria. Dentro del método main, llamamos a un método que coge como argumento una línea del corpus que analizamos y devuelve un objeto de tipo Morpho, que puede ser de una de las subclases de Morpho (pues Morpho no se instancia, es una clase abstracta). Luego llamamos al método imprimir() de este objeto. Lo que pasa es que según que tipo de objeto es, se llama al método imprimir() adecuado, es decir al método imprimir() de Det si el objeto es de tipo Det, al método imprimir() de Nom si el objeto es de tipo Nom, etc. Esta habilidad de un mismo mensaje (el método imprimir()) de comportarse de una forma distinta según el objeto al que esta asociado es polimorfismo. Nos permite recorrer el corpus línea por línea e ir imprimiendo los análisis morfológicos con una sola llamada, sin preocuparnos por el tipo de objeto e el método llamado en concreto.