Aqui achei uma referência legal e atualizada sobre esse assunto: https://www.delftstack.com/pt/howto/java/size-vs-length-in-java/#java-collections-size-m%25C3%25A9todo
Mas resumindo, eis uma diferença importante:
Array em Java tem tamanho fixo, e a propriedade/atributo length é usada para mostrar esse tamanho fixo (ou seja, a capacidade máxima) desse array. Ele não mostra a quantidade de elementos preenchidos, e sim o número de elementos que podem ser armazenados.
Já o método size() é um método da classe java.util.Collections, e por isso apenas pode ser usado por coleções como ArrayList, HashSet, HashMap, etc. Como essas coleções são alocadas dinamicamente, o size() retorna o número de elementos atualmente presentes na coleção.