Checking DnD Traits in an enum
I was thinking of maybe having a constructor for each profession that used true or false to denote if it was a good saving throw or bad one. That's just really bad though, I think, since it doesn't give any information when reading it.


I suppose you mean that this would not be particularly readable:

enum ProfessionType {
    BARBARIAN(false, true, false),
    BARD(true, false, true),
    WIZARD(true, false, false);
    // ...
}


Instead of booleans, you could use enums, like Will.STRONG, Fortitude.WEAK, and so on.
The result will be more readable and less boilerplate.

With this refactoring,
the methods like getWillModifier will be no longer abstract,
and would contain the logic (probably a switch) to get the right value given the property of the enum, and the level.

In general, enums are not so well-suited to have behaviors (custom methods),
they are much better as plain values,
possibly with some common behavior (non-abstract methods).

Another alternative world be to use the builder pattern to build attributes, with a syntax like this:

BARBARIAN(Attributes.builder().will(WEAK).fortitude(STRONG).build()),


Where WEAK and STRONG could come from a Defense enum.

That said, the other answer makes an excellent point that perhaps the attributes should not be hardcoded, but read from a configuration file. You would gain a lot of flexibility, such as adding new types or changing the attributes without recompiling the code.