Exercício sobre captura de exceções com superclasse

Estou com dúvida em um exercício sobre exceções de programação orientada a objetos na linguagem Java. Fiz um código aqui, mas não sei está certo. Se estiver incorreto, gostaria que falassem o que eu tenho que alterar.

Enunciado: Utilize herança para criar uma superclasse de exceção (chamada ExceptionA) e subclasses de exceção ExceptionB e ExceptionC, em que ExceptionB herda de ExceptionA e ExceptionB herda de ExceptionB. Escreva um programa para demonstrar que o bloco catch para o tipo ExceptionA captura exeções de tipos ExceptionB e ExceptionC.

Classe ExcecaoA

public class ExcecaoA
{
	public static void lancaExcecao() throws Exception
	{
		try
		{
			System.out.println( "Superclasse ExcecaoA." );
			ExcecaoB.lancaExcecaoB();
		}
		catch( Exception exception ) // não executa
		{
			System.err.println( "Captura ExcecacoB e ExcecaoC" );
		}
	}
}

Classe ExcecaoB

public class ExcecaoB extends ExcecaoA
{
	public static void lancaExcecaoB() throws Exception
	{
		try
		{
			System.out.println( "Metodo lancaExcecaoB" );
			ExcecaoC.lancaExcecaoC();
		}
		catch( Exception exception ) // não executa
		{
			System.err.println( "" );
		}
	}	
}

Classe ExcecaoC

public class ExcecaoC extends ExcecaoB
{
	public static void lancaExcecaoC() throws Exception
	{
		try
		{
			System.out.println( "Metodo lancaExcecaoC" );
			throw new Exception();
		}
		catch( Exception exception ) // não executa
		{
			System.err.println( "" );
		}
	}
}

Classe CapturaExcecoes( Programa )

public class CapturandoExcecoes
{
	public static void main( String[] args )
	{
		try
		{
			ExcecaoA.lancaExcecao();
		}
		catch( Exception exception )
		{
			System.err.println( "Metodo Main captura excecao de ExcecaoA" );
		}
	}
}

[b]
Saída no CMD:

Superclasse ExcecaoA.
Metodo lancaExcecaoB
Metodo lancaExcecaoC

Tá incorreto sim.

O primeiro ponto é que para uma classe ser usada com o try / catch, ela precisa estender direta ou indiretamente a classe Throwable.

Normalmente vc não vai estender Throwable diretamente, vc vai estender Exception (para exceções que vc quer que o compilador te obrigue a tratar) ou RuntimeException (para excecões que vc não é obrigada a tratar).

Então a ExceptionA ficaria assim:

class ExceptionA extends Throwable {
}

Já as outras duas ficariam assim:

class ExceptionB extends ExceptionA {
}

class ExceptionC extends ExceptionB {
}

O segundo ponto é o código que faz a demonstração. Ele deveria tratar ExceptionA para demonstrar que ele pode capturar tanto exceções de tipo ExceptionA quando ExceptionB e ExceptionC, já que elas são suas subclasses.

class Program {
  public static void main(String... args) {
    try {
      throw new ExceptionA();
    } catch (ExceptionA e) {
      System.out.println("Teste 1: " +e.getClass());
    }

    try {
      throw new ExceptionB();
    } catch (ExceptionA e) {
      System.out.println("Teste 2: " +e.getClass());
    }

    try {
      throw new ExceptionC();
    } catch (ExceptionA e) {
      System.out.println("Teste 3: " +e.getClass());
    }
  }
}

O resultado será:

Teste 1: class ExceptionA
Teste 2: class ExceptionB
Teste 3: class ExceptionC

Consegui entender agora.
Valeu pela explicação!

1 curtida

Aproveitando para perguntar, o que mudaria nesse programa?

Enunciado: Escreva um programa que demonstra como várias exceções são
capturadas com
catch (Exception exception). Desta vez, defina as classes ExceptionA (que herda da
classe Exception) e ExceptionB (que herda da classe ExceptionA). Em
seu programa, crie blocos try que lançam exceções de tipos ExceptionA, ExceptionB,
NullPointerException e IOException. Todas as exceções devem ser capturadas com
blocos catch para especificar o tipo Exception.

Veja se eu entendi direito:

O enunciado quer que vc crie 4 try/catch. Cada try vai lançar uma exceção diferente, mas todos os catch devem capturar o tipo Exception.

Se for isso mesmo, seria algo assim:

import java.io.IOException;

class Program {
  public static void main(String... args) {
    try {
      throw new ExceptionA();
    } catch (Exception e) {
      System.out.println(e.getClass());
    }

    try {
      throw new ExceptionB();
    } catch (Exception e) {
      System.out.println(e.getClass());
    }

    try {
      throw new NullPointerException();
    } catch (Exception e) {
      System.out.println(e.getClass());
    }

    try {
      throw new IOException();
    } catch (Exception e) {
      System.out.println(e.getClass());
    }
  }
}

class ExceptionA extends Exception {
}

class ExceptionB extends ExceptionA {
}