3 ms·
Serious question: why are there accessor methods on records? Record fields are final, so they can’t be modified. Records can’t be extended; so the methods can’
by doctor_eval 7y ago
Serious question: why are there accessor methods on records?
Record fields are final, so they can’t be modified. Records can’t be extended; so the methods can’t be overridden, which means that the accessor methods don’t protect the fields from change or allow for redefinition. Accessor methods are not appropriately named for JavaBeans, so that’s not the reason either.
AFAIK the accessor methods generated by the compiler are in all ways functionally equivalent to simply accessing the fields directly.
But the accessor methods take up more space and add code to the class which increases class size and could be avoided. It’s slightly more cumbersome to use value() instead of just value. And, presumably, compilation takes slightly longer as the compiler (hopefully?) elides the method call and... replaces it with a direct field access.
There must be a benefit to all these costs, but what is it? what is their purpose? why do they exist?
Serious question, I can’t work it out and it’s driving me nuts.
Edit: turns out I’m wrong, methods can be overridden, I misread an article. It makes more sense now.
- threatofrain 7y agoDerived properties perhaps, so you don’t have ad hoc functions floating about. If you need a function to calculate a derived property then you’re gonna pay the price anyway.
- kasperni 7y agoThere are things such as arrays that you cannot really make immutable as things are at the moment. So you will have to override the accessor and provide a copy of the array. If the components were fields you would not be able to do this. Also if you are designing APIs for others to use. You might in some situations want to expose an interface instead of an actual record. As records are difficult to evolve. So having methods are much easier than fields in those situations. For example, the JDK itself mostly plans to use records behind interfaces.
- doctor_eval 7y agoIt’s not clear that this is how records work though. I think only the top level fields are final - I don’t think there’s an expectation that the array contents would be immutable - and since you can’t redefine the methods, this would have to be done by the compiler and I don’t think that’s the case. Also, same problem happens with fields which are instances of classes; although the record is mutable, the instances are not. So I don’t think that’s the answer. I also don’t think records can implement interfaces.
- kasperni 7y agoYes, you can override accessors and mutability is the main reason. It has been discussed a number of times on the various amber mailing lists, here is one [1]. Yes, records can implement interfaces. The syntax is {ClassModifier} record TypeIdentifier [TypeParameters] RecordHeader [SuperInterfaces] RecordBody [1] https://mail.openjdk.java.net/pipermail/amber-spec-experts/2019-March/001046.html https://mail.openjdk.java.net/pipermail/amber-spec-experts/2...
- doctor_eval 7y agoOK thanks. I misread an article as saying that records couldn’t be extended, but on rereading, it actually said that java.lang.Record couldn’t be extended other than by declaring a record. That makes a lot more sense, and certainly explains the use of methods instead of fields. Thanks! (I continue to dislike the syntax, FWIW)
- pron 7y agoYes, deeper immutability and interfaces, but it also allows you use method references. Getting all the x components of a collection of Foo is just: foos.stream().map(Foo::x)