Я сравниваю с Java, который часто имеет переменные-члены как private, так и общедоступные сеттеры и геттеры для каждой переменной-члена.
Это именно то, что происходит в коде Kotlin. name
это не поле (то, что вы называете переменной-членом), это свойство с частным вспомогательным полем. И если вы измените его геттер и сеттер:
var name: String
get() = ...
set(value: String) { ... }
абоненты продолжают использовать
person.name = "kevvex"
и не требует перекомпиляции.
т.е. var name: String = "unknown"
равно точно эквивалентно Java
private String _name = "unknown";
public String getName() { return _name; }
public void setName(String name) { this._name = name; }
и даже будет видно с Java таким образом. Так что это нарушает инкапсуляцию в той же степени, что и Java.