Я использую оба. Я думаю, что они дополняют друг друга.
Как вы сказали, PMD работает с исходным кодом и поэтому обнаруживает такие проблемы, как: нарушение соглашений об именах, отсутствие фигурных скобок, неуместная проверка нуля, длинный список параметров, ненужный конструктор, отсутствие прерывания в переключателе, и т. д. PMD также расскажет вам о цикломатической сложности вашего кода, что я считаю очень полезным (FindBugs не говорит вам о цикломатической сложности).
FindBugs работает с байт-кодом. Вот некоторые проблемы, которые FindBugs находит, а PMD не находит: метод equals () завершается с ошибкой для подтипов, метод clone может возвращать ноль, ссылочное сравнение логических значений, невозможное приведение, 32-битное int, смещенное на величину, не находящуюся в диапазоне 0-31 коллекция, которая содержит себя, метод equals всегда возвращает true, бесконечный цикл и т. д.
Обычно каждый из них находит свой набор проблем. Используйте оба. Эти инструменты научили меня тому, как писать хороший Java-код.