In C++, I can define an accessor member function that returns the value of (or reference to) a private data member, such that the caller cannot modify that private
One way to avoid this issue is to no expose the data structure (another is returning a copy, or an immutable wrapper)
e.g. instead of
public List<String> getSomeList();
have
public String getSomeElement(int index);
This does not exist in java. final and const have different semantics, except when applied to a variable of a primitive type. The java solution typically involves creating immutable classes - where objects are initialized in construction and provide no accessors allowing change. Example of such classes would be e.g. String or Integer.
You haven't overlooked anything. There is no way in pure Java to do so. There might be libraries which provide some subset of this using annotations, but I don't know any offhand.
The way you pass back a reference to immutable data is to make the class you pass back immutable, plain and simple. There are a couple of library functions to help you produce an immutable view of some data in some very limited but common cases. Here's one example:
private List<String> internalData;
public List<String> getSomeList() {
return Collections.unmodifiableList(internalData);
}