Search code examples
javaautoboxingcompile-time-constant

constant expression required in Java behaviour change for int and Integer


For a little code , willing to save some Boxing/Unboxing hassle introduced because I further have to use an int constant as an Integer (mandated by Generics method call), I went from this simplified example

enum SOQ {
    TYPEA,
    TYPEB,
    TYPEC;
    public static final int width = 10;

    public static SOQ of(int i) {
        switch (i) {
            case UIOrdinals.TYPEA_ORD:
                return TYPEA;
            case UIOrdinals.TYPEB_ORD:
                return TYPEB;
            case UIOrdinals.TYPEC_ORD:
                return TYPEC;
        }
        throw new UnsupportedOperationException("Not supported yet."); //TODO : implement
    }

    public static class UIOrdinals {

        public static final int TYPEA_ORD = width * 1;
        public static final int TYPEB_ORD = width * 2;
        public static final int TYPEC_ORD = width * 3;
    }
}

to this

enum SOQBOX {
    TYPEA,
    TYPEB,
    TYPEC;
    public static final Integer width = 10;

    public static SOQBOX of(int i) {
        switch (i) {
            case UIBoxOrdinals.TYPEA_ORD:
                return TYPEA;
            case UIBoxOrdinals.TYPEB_ORD:
                return TYPEB;
            case UIBoxOrdinals.TYPEC_ORD:
                return TYPEC;
        }
        throw new UnsupportedOperationException("Not supported yet."); //TODO : implement
    }

    public static class UIBoxOrdinals {

        public static final Integer TYPEA_ORD = width * 1;
        public static final Integer TYPEB_ORD = width * 2;
        public static final Integer TYPEC_ORD = width * 3;
    }
}

No such a big deal.

As I said I went this way because a helper method relaying on 'width'. This method (which will be called very often) needed some generic type parameters (no primitive allowed), so there came the need for introducing Integer.

Well seems obvious to my eyes that the TYPEnnn_ORD where still constant, and still compile-time-constant but that's not the point of view of the java compiler : "constant expression required" is the error.

Just wanted to know why in this simple case ? It has to do with the boxing, but how and why ?

Meanwhile ,I just went back to the primitive int, hoping moderns jdk like Jdk 8 and Jdk 9 won't waste so much effort in boxing/unboxing.

By the way, as a subsidiary, you know how java competes on this point nowadays ? Is this something we should still minimize ?


Solution

  • Auto-unboxing works by calling the appropriate method in the background. Integer.intValue() in your case. You cannot call a method in the case statement it must be a primitive value to check.