Nao posso testar o código, mas não é preciso, vou responder pela lógica do seu código.
IOException herda de java.lang.Exception. A API do Java diz que toda exceção que herda de Exception, que não seja uma RuntimeException é do tipo checked. E diz ainda que toda checked exception deve capturar ou declarar que lança a exceção.
Você declarou que classe.A.metodo() lança uma IOExeption. Isto está correto, e diferente do que o sergiotaborda falou, o método que sobreescrever este método NÃO precisa ter uma assinatura exatamente igual, o que o método que sobreescrever nunca pode fazer é declarar novas checked exceptions.
Por exemplo, o código está correto:
static class A {
void metodo() throws java.io.IOException {
System.out.println("a");
throw new IOException();
}
}
static class B extends A {
void metodo() throws java.lang.StringIndexOutOfBoundsException
{
System.out.println("b");
}
}
O nosso metodo() sobreescreverá o metodo() da classe A num ambiente polimórfico e não há erro de compilação.
Voltando ao seu código, para resolver seu problema voce tem que lembrar que apesar da versão chamada pelo JVM ser classe.B.metodo(), a versão que o compilador vê é classe.A.metodo(), e como você declarou que LANÇA UMA CHECKED EXCEPTION no metodo() da classe.A então voce deve tratar está possibilidade com um bloco try {}catch().
Acredito que o seguinte código vai compilar a exibir b:
import java.io.IOException;
public class classe {
static class A {
void metodo() throws IOException {
System.out.println("a");
throw new IOException();
}
}
static class B extends A {
void metodo(){
System.out.println("b");
}
}
public static void main(String[] args) {
A a = new B();
try{
a.metodo(); //tratando checked exceptions que O COMPILADOR vê
}catch(IOException ioe){System.err.println("Exceção jamais lançada em tempo de execução");}
}
}