Olá, Anderson! Tudo bem?
Na criação de exceções customizadas, é recomendado estender a classe RuntimeException quando se trata de exceções do tipo unchecked, ou seja, aquelas que não precisam ser obrigatoriamente tratadas pelo desenvolvedor. Por outro lado, é interessante estender a classe Exception quando se trata de exceções do tipo checked, ou seja, aquelas que precisam ser obrigatoriamente tratadas pelo desenvolvedor.
Quando você estende a classe Exception, você está obrigando o desenvolvedor a tratar a exceção ou lançá-la novamente para que seja tratada em outro ponto do programa. Isso é útil em casos em que a exceção pode ser tratada de forma específica em algum ponto do programa.
Quanto à sua segunda pergunta, se um método lança uma exceção do tipo RuntimeException, você não precisa declarar essa exceção no método que o chama. Isso ocorre porque as exceções do tipo RuntimeException não precisam ser obrigatoriamente tratadas pelo desenvolvedor. No entanto, se você quiser que a exceção seja tratada em algum ponto do programa, é possível capturá-la e tratá-la de forma específica.
Espero ter ajudado e bons estudos!