I have recently discovered the Objects.hash() method.
My first thought was, that this tidies up your hashCode() implementation a lot. See the following
Personally I'd side with the short code first, because it is so much quicker to read, change and verify as correct, which all serve to avoid bugs when modifying the class.
Then for performance-critical classes or where fields are costly to hash, I would cache the result (like String does):
// volatile not required for 32-bit sized primitives
private int hash;
@Override
public final int hashCode() {
// "Racy Single-check idiom" (Item 71, Effective Java 2nd ed.)
int h = hash;
if (h == 0) {
h = Objects.hash(id, timestamp, severity, thread, classPath, message);
hash = h;
}
return h;
}
In this lockless-threadsafe pattern (which assumes an immutable class, naturally) there's a slim chance that hash might get initialised by different threads multiple times, but this does not matter because the result of the public method is always identical. The key to (memory-visibility) correctness is ensuring that hash is never written and read more than once in the method.
The array-construction penalty of Objects.hash might be lower than you imagine once the code gets JIT-inlined & optimised by the C2 compiler. Fortunately the good JDK folks have something baking that should essentially eliminate all the overheads of using it: JEP 348: Java Compiler Intrinsics for JDK APIs