Все сводится к проверенному исключению против непроверенного исключения.
Не проверенные исключения являются подклассами из RuntimeException. Они могут быть выброшены без необходимости объявления в сигнатуре метода. Если они не пойманы, их бросают дальше в стек. Так что, если B выбрасывает неконтролируемое Исключение, A тоже его подбрасывает. Компилятор не будет проверять, обрабатываются ли непроверенные исключения, вы увидите это только во время выполнения, отсюда и название RuntimeException.
Проверенные исключения должны быть объявлены в сигнатуре и должны быть обработаны, либо в сигнатуре метода вызывающего метода должно быть указано, что исключение выдается. В противном случае компилятор будет жаловаться, и вы не сможете скомпилировать программу. Так что, если B генерирует CheckedException, например FileNotFoundException, вы должны объявить его в подписи B. Поскольку А не ловит его, его бросают дальше. Объявление A для выдачи исключения в этом случае работает, но это плохая практика.