Given:
public enum PersonType {
    COOL_GUY(1),
    JERK(2);
    private final int typeId;
    private PersonType(int typeId) {
        this.typeId = typeId;
    }
    public final int getTypeId() {
        return typeId;
    }
    public static PersonType findByTypeId(int typeId) {
        for (PersonType type : values()) {
            if (type.typeId == typeId) {
                return type;
            }
        }
        return null;
    }
}
For me, this typically aligns with a look-up table in a database (for rarely-updated tables only).
However, when I try to use findByTypeId in a switch statement (from, most likely, user input)...
int userInput = 3;
PersonType personType = PersonType.findByTypeId(userInput);
switch(personType) {
case COOL_GUY:
    // Do things only a cool guy would do.
    break;
case JERK:
    // Push back. Don't enable him.
    break;
default:
    // I don't know or care what to do with this mess.
}
...as others have stated, this results in an NPE @ switch(personType) {. One work-around (i.e., "solution") I started implementing was to add an UNKNOWN(-1) type.
public enum PersonType {
    UNKNOWN(-1),
    COOL_GUY(1),
    JERK(2);
    ...
    public static PersonType findByTypeId(int id) {
        ...
        return UNKNOWN;
    }
}
Now, you don't have to do null-checking where it counts and you can choose to, or not to, handle UNKNOWN types. (NOTE: -1 is an unlikely identifier in a business scenario, but obviously choose something that makes sense for your use-case).