Preguntas de la entrevista sobre las excepciones de Java (+ respuestas)

Este artículo es parte de una serie: • Preguntas de la entrevista sobre las colecciones de Java

• Preguntas de la entrevista del sistema de tipo Java

• Preguntas de la entrevista de simultaneidad de Java (+ respuestas)

• Preguntas de la entrevista de inicialización y estructura de clases de Java

• Preguntas de la entrevista de Java 8 (+ respuestas)

• Gestión de la memoria en preguntas de la entrevista de Java (+ respuestas)

• Preguntas de la entrevista de Java Generics (+ Respuestas)

• Preguntas de la entrevista de control de flujo de Java (+ respuestas)

• Preguntas de la entrevista sobre las excepciones de Java (+ respuestas) (artículo actual) • Preguntas de la entrevista sobre las anotaciones de Java (+ respuestas)

• Preguntas principales de la entrevista del Spring Framework

1. Información general

Las excepciones son un tema esencial con el que todo desarrollador de Java debería estar familiarizado. Este artículo proporciona respuestas a algunas de las preguntas que pueden surgir durante una entrevista.

2. Preguntas

Q1. ¿Qué es una excepción?

Una excepción es un evento anormal que ocurre durante la ejecución de un programa e interrumpe el flujo normal de las instrucciones del programa.

Q2. ¿Cuál es el propósito de las palabras clave Throw and Throws?

La palabra clave throws se usa para especificar que un método puede generar una excepción durante su ejecución. Impone el manejo explícito de excepciones al llamar a un método:

public void simpleMethod() throws Exception { // ... }

La palabra clave throw nos permite lanzar un objeto de excepción para interrumpir el flujo normal del programa. Esto se usa más comúnmente cuando un programa no cumple con una condición determinada:

if (task.isTooComplicated()) { throw new TooComplicatedException("The task is too complicated"); }

Q3. ¿Cómo se puede manejar una excepción?

Usando una declaración try-catch-finalmente :

try { // ... } catch (ExceptionType1 ex) { // ... } catch (ExceptionType2 ex) { // ... } finally { // ... }

El bloque de código en el que puede producirse una excepción se incluye en un bloque try . Este bloque también se denomina código "protegido" o "guardado".

Si ocurre una excepción, se ejecuta el bloque catch que coincide con la excepción lanzada, si no, se ignoran todos los bloques catch .

El bloque finalmente siempre se ejecuta después de que sale el bloque try , ya sea que se haya lanzado una excepción o no dentro de él.

Q4. ¿Cómo se pueden detectar varias excepciones?

Hay tres formas de manejar múltiples excepciones en un bloque de código.

La primera es usar un bloque de captura que pueda manejar todos los tipos de excepciones que se lanzan:

try { // ... } catch (Exception ex) { // ... }

Debe tener en cuenta que la práctica recomendada es utilizar controladores de excepciones que sean lo más precisos posible.

Los controladores de excepciones que son demasiado amplios pueden hacer que su código sea más propenso a errores, detectar excepciones que no fueron anticipadas y causar un comportamiento inesperado en su programa.

La segunda forma es implementar múltiples bloques de captura:

try { // ... } catch (FileNotFoundException ex) { // ... } catch (EOFException ex) { // ... }

Tenga en cuenta que, si las excepciones tienen una relación de herencia; el tipo hijo debe ir primero y el tipo padre después. Si no lo hacemos, se producirá un error de compilación.

El tercero es usar un bloque de captura múltiple:

try { // ... } catch (FileNotFoundException | EOFException ex) { // ... }

Esta característica, introducida por primera vez en Java 7; reduce la duplicación de código y facilita su mantenimiento.

Q5. ¿Cuál es la diferencia entre una excepción marcada y una no marcada?

Una excepción marcada debe manejarse dentro de un bloque try-catch o declararse en una cláusula throws ; mientras que una excepción no marcada no requiere ser manejada ni declarada.

Las excepciones marcadas y no marcadas también se conocen como excepciones en tiempo de compilación y en tiempo de ejecución, respectivamente.

Todas las excepciones son excepciones comprobadas, excepto las indicadas por Error , RuntimeException y sus subclases.

Q6. ¿Cuál es la diferencia entre una excepción y un error?

Una excepción es un evento que representa una condición de la que es posible recuperarse, mientras que el error representa una situación externa de la que generalmente es imposible recuperarse.

Todos los errores lanzados por la JVM son instancias de Error o una de sus subclases, los más comunes incluyen, pero no se limitan a:

  • OutOfMemoryError : se lanza cuando la JVM no puede asignar más objetos porque no tiene memoria y el recolector de basura no pudo hacer más disponibles
  • StackOverflowError : se produce cuando se agota el espacio de la pila para un hilo, normalmente porque una aplicación recurre demasiado profundamente
  • ExceptionInInitializerError : indica que se produjo una excepción inesperada durante la evaluación de un inicializador estático
  • NoClassDefFoundError – is thrown when the classloader tries to load the definition of a class and couldn't find it, usually because the required class files were not found in the classpath
  • UnsupportedClassVersionError – occurs when the JVM attempts to read a class file and determines that the version in the file is not supported, normally because the file was generated with a newer version of Java

Although an error can be handled with a try statement, this is not a recommended practice since there is no guarantee that the program will be able to do anything reliably after the error was thrown.

Q7. What Exception Will Be Thrown Executing the Following Code Block?

Integer[][] ints = { { 1, 2, 3 }, { null }, { 7, 8, 9 } }; System.out.println("value = " + ints[1][1].intValue());

It throws an ArrayIndexOutOfBoundsException since we're trying to access a position greater than the length of the array.

Q8. What Is Exception Chaining?

Occurs when an exception is thrown in response to another exception. This allows us to discover the complete history of our raised problem:

try { task.readConfigFile(); } catch (FileNotFoundException ex) { throw new TaskException("Could not perform task", ex); }

Q9. What Is a Stacktrace and How Does It Relate to an Exception?

A stack trace provides the names of the classes and methods that were called, from the start of the application to the point an exception occurred.

It's a very useful debugging tool since it enables us to determine exactly where the exception was thrown in the application and the original causes that led to it.

Q10. Why Would You Want to Subclass an Exception?

If the exception type isn't represented by those that already exist in the Java platform, or if you need to provide more information to client code to treat it in a more precise manner, then you should create a custom exception.

Deciding whether a custom exception should be checked or unchecked depends entirely on the business case. However, as a rule of thumb; if the code using your exception can be expected to recover from it, then create a checked exception otherwise make it unchecked.

Also, you should inherit from the most specific Exception subclass that closely relates to the one you want to throw. If there is no such class, then choose Exception as the parent.

Q11. What Are Some Advantages of Exceptions?

Traditional error detection and handling techniques often lead to spaghetti code hard to maintain and difficult to read. However, exceptions enable us to separate the core logic of our application from the details of what to do when something unexpected happens.

Also, since the JVM searches backward through the call stack to find any methods interested in handling a particular exception; we gain the ability to propagate an error up in the call stack without writing additional code.

Also, because all exceptions thrown in a program are objects, they can be grouped or categorized based on its class hierarchy. This allows us to catch a group of exceptions in a single exception handler by specifying the exception's superclass in the catch block.

Q12. Can You Throw Any Exception Inside a Lambda Expression's Body?

When using a standard functional interface already provided by Java, you can only throw unchecked exceptions because standard functional interfaces do not have a “throws” clause in method signatures:

List integers = Arrays.asList(3, 9, 7, 0, 10, 20); integers.forEach(i -> { if (i == 0) { throw new IllegalArgumentException("Zero not allowed"); } System.out.println(Math.PI / i); });

However, if you are using a custom functional interface, throwing checked exceptions is possible:

@FunctionalInterface public static interface CheckedFunction { void apply(T t) throws Exception; }
public void processTasks( List taks, CheckedFunction checkedFunction) { for (Task task : taks) { try { checkedFunction.apply(task); } catch (Exception e) { // ... } } } processTasks(taskList, t -> { // ... throw new Exception("Something happened"); });

Q13. What Are the Rules We Need to Follow When Overriding a Method That Throws an Exception?

Several rules dictate how exceptions must be declared in the context of inheritance.

When the parent class method doesn't throw any exceptions, the child class method can't throw any checked exception, but it may throw any unchecked.

Here's an example code to demonstrate this:

class Parent { void doSomething() { // ... } } class Child extends Parent { void doSomething() throws IllegalArgumentException { // ... } }

The next example will fail to compile since the overriding method throws a checked exception not declared in the overridden method:

class Parent { void doSomething() { // ... } } class Child extends Parent { void doSomething() throws IOException { // Compilation error } }

When the parent class method throws one or more checked exceptions, the child class method can throw any unchecked exception; all, none or a subset of the declared checked exceptions, and even a greater number of these as long as they have the same scope or narrower.

Here's an example code that successfully follows the previous rule:

class Parent { void doSomething() throws IOException, ParseException { // ... } void doSomethingElse() throws IOException { // ... } } class Child extends Parent { void doSomething() throws IOException { // ... } void doSomethingElse() throws FileNotFoundException, EOFException { // ... } }

Note that both methods respect the rule. The first throws fewer exceptions than the overridden method, and the second, even though it throws more; they're narrower in scope.

However, if we try to throw a checked exception that the parent class method doesn't declare or we throw one with a broader scope; we'll get a compilation error:

class Parent { void doSomething() throws FileNotFoundException { // ... } } class Child extends Parent { void doSomething() throws IOException { // Compilation error } }

When the parent class method has a throws clause with an unchecked exception, the child class method can throw none or any number of unchecked exceptions, even though they are not related.

Here's an example that honors the rule:

class Parent { void doSomething() throws IllegalArgumentException { // ... } } class Child extends Parent { void doSomething() throws ArithmeticException, BufferOverflowException { // ... } }

Q14. Will the Following Code Compile?

void doSomething() { // ... throw new RuntimeException(new Exception("Chained Exception")); }

Yes. When chaining exceptions, the compiler only cares about the first one in the chain and, because it detects an unchecked exception, we don't need to add a throws clause.

Q15. Is There Any Way of Throwing a Checked Exception from a Method That Does Not Have a Throws Clause?

Yes. We can take advantage of the type erasure performed by the compiler and make it think we are throwing an unchecked exception, when, in fact; we're throwing a checked exception:

public  T sneakyThrow(Throwable ex) throws T { throw (T) ex; } public void methodWithoutThrows() { this.sneakyThrow(new Exception("Checked Exception")); }

3. Conclusion

En este artículo, hemos explorado algunas de las preguntas que pueden aparecer en entrevistas técnicas para desarrolladores de Java, con respecto a las excepciones. Esta no es una lista exhaustiva y debe tratarse solo como el comienzo de una mayor investigación.

En Baeldung, le deseamos éxito en las próximas entrevistas.

Siguiente » Preguntas de la entrevista sobre anotaciones de Java (+ respuestas) « Preguntas anteriores de la entrevista sobre el control de flujo de Java (+ respuestas)