La razón principal para no solo hacer que la variable sea pública en primer lugar es que si la hiciera pública, crearía más dolores de cabeza más adelante.
Por ejemplo, un programador escribe getters y setters públicos alrededor de una variable de miembro privada. Tres meses después, necesita verificar que la variable nunca se "establece" como nula. Agrega un cheque en el método "setFoo (...)", y todos los intentos de establecer la variable se verificarán para "configurarlo en nulo". Caso cerrado, y con poco esfuerzo.
Otro programador se da cuenta de que poner getters y setters públicos alrededor de una variable de miembro privado está violando el espíritu de encapsulación, ve la inutilidad de los métodos y decide hacer pública la variable miembro. Tal vez esto aumente un poco el rendimiento, o quizás el programador solo quiera "escribirlo tal como se usa". Tres meses después, necesita verificar que la variable nunca se "establece" como nula. Escanea todos los accesos a la variable, buscando efectivamente a través de la base de códigos completa, incluyendo todos los códigos que podrían acceder a la variable a través de la reflexión. Esto incluye todas las bibliotecas de terceros que han extendido su código, y todos los módulos recientemente escritos que usaron su código después de haber sido escrito. Luego modifica todas las llamadas para garantizar que la variable nunca se establezca como nula. El caso nunca se cierra, porque no puede encontrar efectivamente todos los accesos al miembro expuesto, ni tiene acceso a todos los códigos fuente de terceros. Con un conocimiento imperfecto de los módulos recién escritos, se garantiza que la encuesta estará incompleta. Finalmente, no tiene control sobre el código futuro que puede acceder al miembro público, y ese código puede contener líneas que establecen la variable miembro como nula.
Por supuesto, el segundo programador podría romper todos los códigos existentes poniendo métodos "get" y "set" alrededor de la variable y haciéndola privada, pero hey, podría haberlo hecho tres meses antes y haberse guardado la explicación de por qué necesitaba romper el código de todos los demás.
Llámelo como lo desee, pero poner métodos públicos de "obtener" y "establecer" en torno a una variable miembro privada es una programación defensiva que se ha llevado a cabo por muchos años (es decir, décadas) de experiencia.
También facilita la depuración, ya que puede agregar registros o puntos de interrupción o lo que sea dentro de sus getters y setters. – Brian