I, personally, avoid Lombok, specifically because I care about implementation details. Because if I would have wanted better Java, I'd go with Kotlin rather than this hacky way of using another Java-like language. But other people hold different opinions.
The 10% lombok can do because it's peaking at internals isn't valuable. I don't, for example, need an annotation to create a static logger. That's dumb.
I dont use lombok and the latter has been actively removed. If you have access to records, lombok is just bad. Even if you dont have - public final fields are sufficient in most case + c-tor and validation there. Just dont use getters & setters.
Records have reduced the advantages of Lombok by a boatload. But there still are some things that can't be records.
That's a fundamental misunderstanding of hashCode, and lombok makes no exception. Not all fields need to be used to calculate hashCode, it makes the overall performance worse in most cases. Equals is of course different, however if you have an identity (i.e. database primary key), only the identity should be used.
I've seen so many performance issues with hashcode because devs will put all fields into it. Even though there's an id column or even fields that imply other fields. Hashing 1000 char strings when there's a UUID or int field that guarantees identity is silly.
I think it's because devs have an preference for symmetry. I see the same thing happen when they preferably add setters for all fields even though they aren't necessary.
Realistically, I have trained quite a few folks on my own.
>I think it's because devs have an preference for symmetry.
Another option is that's the default for all IDEs auto gen, so few clicks/taps and it's done.
My favorite question on interviews is explaining all methods of class Object, including the contract and best practices for equals/hashCode. Failure to answer this question automatically disqualifies applicants to mid-level and senior positions.
finalize() is actually is a very hard mode; I'd not expect any extra senior to be able to explain it properly (incl. the semantics of JMM, the fact half created objects can be finalized; the resurrection ability). Deprecated now, so perhaps no need?
wait/notify/notifyAll - easier, still require some practice, also not that useful any longer; but still I'd expect to know not to use a naked notify and how to properly use a loop around wait
clone() - it'd be a hard nut for many, and I have seen more than enough implementations that straight out use new XXX(); not very difficult but not intuitive
hashCode/equals -> hashCode being by default a random number generator is sort of cool; yes they are the backbone of all collection framework; also the value of the not overridden hashCode() is available through System.identifyHashCode()
getClass() - if included anonymous classes, it might puzzle some
toString() - finally something easy
---flip note: the standard templates for intellij could use some work when it comes to the quality of hashCode;
> Deprecated now, so perhaps no need?
Yes. Worth mentioning existence and “do not touch it”, but no need to go deep. Same with clone. The point of this exercise is to demonstrate that you can use the core library without shooting yourself in the foot. As for wait/notify/notifyAll, I’d expect the correct usage patterns from mid-level.
Doesn't everyone just use Objects::hash?
I hope they do know better, it's actually rather poor. 1st it should not be used for a single parameter - just use hashCode() directly and ensure non-null in the c-tor (or Objects.hashCode). Then, in general you need - only few fields to calc a decent high cardinality hashCode...
Last: 31 as a constant (used in most mul/add schemas by java). It's a single byte prime, so it has some benefits. It can be implemented via shift and add (x<<5 - x) but modern CPUs implement mul quite well and don't have carry flag deps so shift+add is worse in general. However, as a constant is more like to cause collisions in a general purpose hash function. It's close to being power of 2 and multiple of 10 -> 32 and 30.
Right. So the parenthetical clause should more correctly state "(or worse, adding them to hashCode but not equals)". That's fine, but it's still the same problem: there's a hidden dependency between changes in two or more locations. People make errors in those kind of updates all the time.
That's proper bad, however it should be noted in a pull request and explained how hashCode operates - people learn and improve.
> there's a hidden dependency between changes in two or more location
True, of course. However, just do not modify hashCode and consider if the extra fields do contribute to equality either.
Realistically I have not seen this error since very early 00s. I have seen use of mutable fields in hashCode, though (and the latter being modified while added to a hashset, used as map keys. lombok encourages such designs).
Another a lot more common error is "compareTo"
The issue is having plainly useless getters and setter (just use public fields); along with the fact that mutable hashCode/equals