Tanto 8.2 quanto 5.2 não podem ser representados exatamente em binário. Então 8.2 é armazenado como um número que é 8.2 mais ou menos um erro muito pequeno, e 5.2 é armazenado como um número que é 5.2 mais ou menos um erro muito pequeno.
Casualmente, quando você subtraiu um número do outro, os erros não se cancelaram, e acabou dando esse número que não é exatamente 3 mas é quase 3, tanto é que se o Java imprimisse o número com menos casas ele iria mostrar arredondado para o valor esperado (3.0).