Improving Design for structured Keys
My initial thought is that you don't :)

The whole idea behind the enum approach starts from your premise:


  Since everything is known from the start I tend to use enum


Which means you're dealing with a specific set with it's own rules and checks that you put into that enum.

If you were to start from the idea of reusing code to represent different kinds of sets you wouldn't go for enums (or static finals for that matter).
That requires a completetly different design.

In this case I'll point out Martin Fowler's rule of three.

More specifically, you should only consider refactoring this for reusability if you actually want to reuse it in the first place.

Also: copy-pasting some code isn't a deadly sin. It's only a bad smell, that you have to decide to remove or not.