Pregunta Java: HashSet sin equals ni hashCode

Piensa la respuesta antes de abrirla. Todas las opciones parecen razonables, y casi siempre hay un detalle que lo cambia todo.

Pregunta Java · Collections

¿Cuál es el resultado de compilar y ejecutar la clase Test?

import java.util.HashSet;
public class Test {
    public static void main(String args[]) {
        HashSet hashset = new HashSet();
        String s1 = new String("uno");
        String s2 = new String("uno");
        CadenaBean s3 = new CadenaBean("dos");
        CadenaBean s4 = new CadenaBean("dos");
        CadenaBean s5 = new CadenaBean("tres");
        hashset.add(s1);
        hashset.add(s2);
        hashset.add(s3);
        hashset.add(s4);
        System.out.println(hashset);
    }
}
class CadenaBean {
    private String str;
    CadenaBean(String str) {
        this.str = str;
    }
    public String toString() {
        return str;
    }
}
  1. [uno,dos,tres]
  2. [uno,uno,dos,dos]
  3. [dos,dos,uno]
  4. No hay garantía del orden.
  5. Error de ejecución
Ver la respuesta

Respuesta: d.

java Test[dos, uno, dos]

Hay tres cosas que mirar:

  • s1 y s2 son objetos distintos, pero String define equals y hashCode por contenido, así que el conjunto los ve iguales y solo guarda uno.
  • CadenaBean no redefine ninguno de los dos y usa los de Object, que comparan identidad. Los dos "dos" cuentan como distintos y entran ambos.
  • s5 se crea pero nunca se añade.

Quedan tres elementos, uno, dos y dos, en un orden que HashSet no garantiza. En nuestra ejecución salió [dos, uno, dos], que se parece a la opción c pero no es lo que el código asegura. La respuesta correcta es la d. (La quinta opción también estaba marcada como «d» en la imagen original.)

Al compilar sale además un aviso, Test.java uses unchecked or unsafe operations, por usar HashSet sin tipo. Hoy se escribiría Set<Object> hashset = new HashSet<>();.

Pregunta publicada en 2014 y revisada en octubre de 2026. La respuesta se comprobó compilando y ejecutando el código con Java 25 LTS en un contenedor limpio; las salidas están copiadas de esa ejecución.

Pregunta Java: un assert que nunca falla

Piensa la respuesta antes de abrirla. Todas las opciones parecen razonables, y casi siempre hay un detalle que lo cambia todo.

Pregunta Java · Assertions

Suponiendo que ejecutas la clase Prueba con java -enableassertions Prueba, ¿cuál es el resultado?

public class Prueba {

    public static void main(String... args) {
        for (int i = 2; i < 4; i++) {
            for (int j = 2; j < 4; j++) {
                if (i < j) {
                    assert i != j : i;
                }
            }
        }

    }
}
  1. Exception in thread "main" java.lang.AssertionError: 1
  2. Exception in thread "main" java.lang.AssertionError: 2
  3. Se ejecuta y no imprime nada
  4. Error de ejecución
Ver la respuesta

Respuesta: c.

java -enableassertions Prueba(no imprime nada)
[código 0]

El assert solo se evalúa cuando i < j, y en ese caso i != j siempre es cierto, así que la condición nunca falla. El valor que va detrás de los dos puntos (: i) solo se usaría como mensaje del AssertionError, y aquí no llega a usarse.

Por omisión, la máquina virtual ignora los assert: hay que activarlos con -enableassertions (o -ea). Por eso no sirven para validar datos de entrada en un programa en producción, sino para comprobar suposiciones durante el desarrollo.

Pregunta publicada en 2014 y revisada en octubre de 2026. La respuesta se comprobó compilando y ejecutando el código con Java 25 LTS en un contenedor limpio; las salidas están copiadas de esa ejecución.

Pregunta Java: llamar a run() en vez de start()

Piensa la respuesta antes de abrirla. Todas las opciones parecen razonables, y casi siempre hay un detalle que lo cambia todo.

Pregunta Java · Threads

¿Cuál es el resultado de compilar y ejecutar la clase Test02?

public class Test02 {
    public static void main(String argv[]) {
        Test1 pm1 = new Test1("Uno");
        pm1.run();
        Test1 pm2 = new Test1("Dos");
        pm2.run();
    }
}

class Test1 extends Thread {
    private String nombre = "";
    Test1(String s) {
        nombre = s;
    }
    public void run() {
        for (int i = 0; i < 2; i++) {
            try {
                sleep(1000);
            } catch (InterruptedException e) {
            }
            yield();
            System.out.println(nombre);
        }
    }
}
  1. Uno Dos
  2. Uno Dos Uno Dos
  3. Uno Uno Dos Dos
  4. Error de ejecución
Ver la respuesta

Respuesta: c.

java Test02  —  con Thread.yield()Uno
Uno
Dos
Dos

El código llama a run() directamente, no a start(). Así no se crea ningún hilo: run() es un método normal que se ejecuta en el hilo principal, de principio a fin, antes de pasar a la línea siguiente. Primero Uno dos veces, luego Dos dos veces, y tarda unos cuatro segundos por los cuatro sleep(1000). Con start(), los dos hilos irían a la vez y lo normal sería ver los nombres intercalados.

En Java actual este código ya no compila tal cual. Desde Java 14, yield es una palabra con significado propio en las expresiones switch, y una llamada sin calificar se rechaza:
javac Test02.java  —  Java 25Test02.java:21: error: invalid use of a restricted identifier 'yield'
            yield();
            ^
  (to invoke a method called yield, qualify the yield with a receiver or type name)
1 error

Basta con escribir Thread.yield();. Con ese cambio se obtuvo la salida de arriba. En 2014, con Java 7 u 8, el código original compilaba.

Pregunta publicada en 2014 y revisada en octubre de 2026. La respuesta se comprobó compilando y ejecutando el código con Java 25 LTS en un contenedor limpio; las salidas están copiadas de esa ejecución.

Pregunta Java: clases internas anidadas

Piensa la respuesta antes de abrirla. Todas las opciones parecen razonables, y casi siempre hay un detalle que lo cambia todo.

Pregunta Java · Clases internas

¿Cuál es el resultado de compilar y ejecutar la clase Prueba1?

public class Prueba1 {
    public class Prueba2 {
        public class Prueba3 {
            public Prueba3(){
                System.out.println("Hola");
            }
            public class Prueba4 {
                public void Prueba4(){
                    System.out.println("Mundo");
                }
            }
        }
    }

    public static void main(String args []){
        Prueba2.Prueba3.Prueba4 p = new Prueba1().new Prueba2().new Prueba3().new Prueba4();
    }
}
  1. No compila por la declaración de las clases Prueba2, Prueba3 y Prueba4 dentro de Prueba1.
  2. No compila porque la declaración de la variable p es incorrecta.
  3. Compila y no imprime nada.
  4. Imprime "Hola Mundo"
  5. Imprime "Hola"
Ver la respuesta

Respuesta: e.

java Prueba1Hola

Las clases internas se pueden anidar sin límite, y para crear una hace falta una instancia de la que la contiene. Eso es justo lo que hace la cadena new Prueba1().new Prueba2().new Prueba3().new Prueba4(), y el tipo Prueba2.Prueba3.Prueba4 es correcto.

La trampa está en public void Prueba4(): por llevar void, no es un constructor, sino un método que se llama igual que la clase. Al hacer new Prueba4() se usa el constructor por defecto, que no imprime nada. El único constructor que escribe algo es el de Prueba3, y por eso solo sale Hola.

Pregunta publicada en 2014 y revisada en octubre de 2026. La respuesta se comprobó compilando y ejecutando el código con Java 25 LTS en un contenedor limpio; las salidas están copiadas de esa ejecución.

Pregunta Java: serializar una clase cuyo padre no es Serializable

Piensa la respuesta antes de abrirla. Todas las opciones parecen razonables, y casi siempre hay un detalle que lo cambia todo.

Pregunta Java · Serialización

¿Cuál es el resultado de ejecutar la clase Prueba?

public class Padre {
    public Padre() {
        System.out.println("Padre");
    }
}
import java.io.Serializable;
public class Hijo extends Padre implements Serializable {
    public Hijo() {
        System.out.println("Hijo");
    }
}
import java.io.*;
public class Prueba {

    public static void main(String... args) throws Exception {
        Hijo a = new Hijo();
        ObjectOutputStream save = new ObjectOutputStream(new FileOutputStream("archivo.txt"));
        save.writeObject(a);
        save.flush();
        System.out.println("-");
        ObjectInputStream restore = new ObjectInputStream(new FileInputStream("archivo.txt"));
        Hijo b = (Hijo) restore.readObject();
    }
}
  1. Padre Hijo – Padre Hijo
  2. Padre Hijo – Padre
  3. Padre – Hijo
  4. Error en tiempo de ejecución
Ver la respuesta

Respuesta: b.

java PruebaPadre
Hijo
-
Padre

Al crear el objeto se ejecutan los dos constructores: Padre y Hijo. Al deserializarlo no se llama al constructor de la clase serializable, porque su estado se recupera del archivo. Pero Padre no es Serializable, así que su parte no se guardó, y Java la reconstruye llamando a su constructor sin parámetros. Por eso sale Padre una vez más, y Hijo no.

De ahí una regla poco conocida: si una clase serializable hereda de una que no lo es, esa clase padre tiene que tener un constructor sin parámetros accesible. Si no lo tiene, la deserialización falla con InvalidClassException.

Pregunta publicada en 2014 y revisada en octubre de 2026. La respuesta se comprobó compilando y ejecutando el código con Java 25 LTS en un contenedor limpio; las salidas están copiadas de esa ejecución.

Pregunta Java: binarySearch con null

Piensa la respuesta antes de abrirla. Todas las opciones parecen razonables, y casi siempre hay un detalle que lo cambia todo.

Pregunta Java · Arrays

¿Cuál es el resultado de compilar y ejecutar el siguiente código? ¿Y por qué?

import java.util.Arrays;

public class Prueba {
  public static void main(String args[]){
    String[] arr = {"texto1", "texto3" , "texto2"};
    Arrays.sort(arr);
    System.out.print(" " + Arrays.binarySearch(arr, "texto2"));
    System.out.print(" " + Arrays.binarySearch(arr, "texto3"));
    System.out.print(" " + Arrays.binarySearch(arr, null));
  }
}
  1. Imprime ' 2 1 -1'
  2. Imprime ' 1 2' y lanza una java.lang.NullPointerException.
  3. Imprime ' 2 1 0'
  4. No compila porque sort no funciona con arreglos de Strings.
Ver la respuesta

Respuesta: 2.

java Prueba1 2Exception in thread "main" java.lang.NullPointerException: Cannot read field "value" because "anotherString" is null
	at java.base/java.lang.String.compareTo(String.java:2105)
	at java.base/java.lang.String.compareTo(String.java:144)
	at java.base/java.util.Arrays.binarySearch0(Arrays.java:2231)
	at java.base/java.util.Arrays.binarySearch(Arrays.java:2171)
	at Prueba.main(Prueba.java:9)

Después de sort el arreglo queda {"texto1", "texto2", "texto3"}, así que "texto2" está en la posición 1 y "texto3" en la 2. Para buscar, binarySearch compara con compareTo, y comparar una cadena con null lanza la excepción. Las dos primeras búsquedas ya se habían impreso, sin salto de línea porque se usa print, y la excepción aparece pegada a ellas.

La imagen original no llevaba import java.util.Arrays;, y sin esa línea el código no compila.

Pregunta publicada en 2013 y revisada en octubre de 2026. La respuesta se comprobó compilando y ejecutando el código con Java 25 LTS en un contenedor limpio; las salidas están copiadas de esa ejecución.

Me

Cuatro siluetas: el optimista, con un corazón; el pesimista, con el corazón roto; el realista, con un corazón anatómico, y «yo», con las palabras Java, C++ y PHP en el pecho.

Hay quien lleva el corazón en el pecho y quien lleva sus lenguajes de programación favoritos.

Pregunta Java: leer más allá del final de un archivo

Piensa la respuesta antes de abrirla. Todas las opciones parecen razonables, y casi siempre hay un detalle que lo cambia todo.

Pregunta Java · IO

Suponiendo que tienes los permisos de lectura y escritura, ¿cuál es el resultado de compilar y ejecutar el siguiente código? ¿Y por qué?

import java.io.*;

public class Prueba {
  public static void main(String[] args)
          throws FileNotFoundException, IOException {
    OutputStream out = new FileOutputStream("/archivo.txt");
    out.write(123);
    out.close();
    InputStream input = new FileInputStream("/archivo.txt");
    System.out.println(input.read() + " " + input.read());
    input.close();
  }
}
  1. imprime "123 0"
  2. imprime "123 -1"
  3. imprime "123 null"
  4. se lanza una excepción en tiempo de ejecución.
Ver la respuesta

Respuesta: 2.

java Prueba123 -1

write(123) escribe un solo byte, con el valor 123. El primer read() lo devuelve, y el segundo ya no tiene nada que leer: read() devuelve -1 al llegar al final del archivo. No lanza una excepción, y tampoco puede devolver null, porque devuelve un int.

Por eso read() devuelve un int y no un byte: necesita un valor más, -1, que no se pueda confundir con ningún byte (0 a 255).

La imagen original no llevaba la línea import java.io.*;, y sin ella el código no compila. Lo de «suponiendo que tienes permisos» importa: escribir en /archivo.txt, en la raíz, solo funciona como administrador. Con un usuario normal da FileNotFoundException: /archivo.txt (Permission denied), y por eso esta ejecución se hizo como root.

Pregunta publicada en 2013 y revisada en octubre de 2026. La respuesta se comprobó compilando y ejecutando el código con Java 25 LTS en un contenedor limpio; las salidas están copiadas de esa ejecución.