Boxing and Widening

前端 未结 7 1628
小蘑菇
小蘑菇 2020-12-30 08:22

What is the difference between these two. I know Boxing is converting primitive values to reference. What is widening. Also what should be the sequence first boxing should b

相关标签:
7条回答
  • 2020-12-30 09:01

    I think the order is pretty fascinating. I made out the following playground to see every possible combination. This are my functions:

    static void doSomeThing(short i) {
        System.out.println("short");
    }
    
    static void doSomeThing(short... i) {
        System.out.println("short...");
    }
    
    static void doSomeThing(Short i) {
        System.out.println("SHORT");
    }
    
    static void doSomeThing(Short... i) {
        System.out.println("SHORT...");
    }
    
    static void doSomeThing(long i) {
        System.out.println("long");
    }
    
    static void doSomeThing(long... i) {
        System.out.println("long...");
    }
    
    static void doSomeThing(Long i) {
        System.out.println("LONG");
    }
    
    static void doSomeThing(Long... i) {
        System.out.println("LONG...");
    }
    
    static void doSomeThing(int i) {
        System.out.println("int");
    }
    
    static void doSomeThing(int... i) {
        System.out.println("int...");
    }
    
    static void doSomeThing(Integer i) {
        System.out.println("INTEGER");
    }
    
    static void doSomeThing(Integer... i) {
        System.out.println("INTEGER...");
    }
    
    static void doSomeThing(Object i) {
        System.out.println("Object");
    }
    
    static void doSomeThing(Object... i) {
        System.out.println("Object...");
    }
    

    Rules:

     1.Searches for exactly the same type (int -> int)
     2.Widening (int -> long)
     3.Boxing (int-> Integer, it is NEVER possible to implicit box AND wide (int -> Long NOT possible without cast))
     !!Multiple boxing go BEFORE var args!!
     int -> Object will be chosen before int -> int...
     4.Var args (int -> int...)
     5.Widening + var args (int -> long...)
     6.Boxing + var args (int -> Integer...)
     7.Boxing + widening + var args (int -> Object...)
    
    public class Main{
    
        public static void main(String...args) {
            //primitive int
            int i = 0;
            doSomeThing(i); //int
            //commented out doSomeThing(int i){}
            doSomeThing(i); //long. It is not possible to narrow, so short, short... Short and Short... will NEVER be called when the input is larger than a short.
            //commented out doSomeThing(long i){}
            doSomeThing(i); //INTEGER
            //commented out doSomething(Integer i){}
            doSomeThing(i); //Object. Notice that there can be multiple boxing before moving to var args
                                //Error occured: compiler if confused: can either execute int..., long..., Object... or Integer...
            //Object... and Integer... are commented out, because in the real world int... will be called first
            doSomeThing(i); //int...
            //commented out int...
            doSomeThing(i); //long...
            //commented out long... and uncommented Integer...
            doSomeThing(i); //Integer...
            //commented out Integer... and uncommented Object...
            doSomeThing(i); //Object...
    
                    //Integer
            //Integer
            Integer i = new Integer(0);
            doSomeThing(i); //INTEGER
            //commented out doSomeThing(Integer i)
            doSomeThing(i); //Object
            //commented out doSomeThing(Object i)
            doSomeThing(i); //int
            //commented out doSomeThing(int i)
            doSomeThing(i); //long so NOT int... it goes widening again
            //commented out doSomeThing(long i)
                            //Error occured: compliler refused: not both have int..., long..., Integer... and Object...
            //int... and long... are commented out
            doSomeThing(i); //INTEGER...
            //commented out doSomeThing(Integer... i)
            doSomeThing(i); //Object...
            //commented out doSomeThing(Object... i)
            //uncommented doSomeThing(int... and long...)
            doSomeThing(i); //int...
            //uncommented doSomeThing(int... i)
            doSomeThing(i); //long...
        }
    
    0 讨论(0)
  • 2020-12-30 09:16

    Widening is transforming a variable in another with a wider type.
    Widening can be done with primitive or reference types.

    For example :

    String -> Object
    int -> long

    As the JLS states :

    a boxing conversion (§5.1.7) [is] optionally followed by a widening reference conversion


    Resources :

    • JLS - Widening Primitive Conversion
    • JLS - Widening Reference Conversions
    0 讨论(0)
  • 2020-12-30 09:17
    1. Widening wins over boxing and var-args
    2. Boxing wins over var-args
    3. Widening of reference variable depends on inheritance(so, Integer cannot be widened to Long. But, Integer widened to Number).
    4. Widen and boxing is not possible
    5. Boxing and widening is possible
    6. var-args can be combined with either boxing or widening
    0 讨论(0)
  • 2020-12-30 09:17
    • Widening beats boxing eg. go(int) will call go(long) instead of go(Integer) if both are available
    • Widening beats var-args eg go(byte,byte) will call go(int,int) instead of go(byte...x) method.
    • Boxing beats var-args eg go(byte,byte) will call go(Byte,Byte) instead of go(byte...x) method.
    • widening depends on inheritance tree. Eg. go(dog) can call go(Animal)
    • primitive wrapper widening is not possible so go(Short) cannot call go(Integer) since they are not in the same inheritance hierarchy .
    • You CANNOT widen and then box. Eg. go(int) cannot call go(Long) since to call go(Long) the compiler need to convert int to Integer then Integer to Long which is not possible.(rule mentioned above)
    • You can box and then widen. Eg. An int can boxed to Integer and then widen to Object
    0 讨论(0)
  • 2020-12-30 09:17

    Widening is the extension of data type into a wider type. Boxing is when primitive data type is wrapped into a container object so that it can be used in Generics, mainly Collections. Eg:

    public class Widening{
    public static void main(String[] args) throws Exception {
    int test = 20;
    myOverloadedFunction(test);
    }
    //static void myOverloadedFunction(long parameter) {
    //System.out.println("I am primitive long");
    //}
    static void myOverloadedFunction(Integer parameter) {
    System.out.println("i am wrapper class Integer");
    }
    }
    

    Output: i am wrapper class Integer (int is wrapped in Integer container)

    Now lets uncomment another overloaded method and see:

    public class Widening{
    public static void main(String[] args) throws Exception {
    int test = 20;
    myOverloadedFunction(test);
    }
    static void myOverloadedFunction(long parameter) {
    System.out.println("I am primitive long");
    }
    static void myOverloadedFunction(Integer parameter) {
    System.out.println("i am wrapper class Integer");
    }
    }
    

    Output: I am primitive long

    Compiler precedence is widening over autoboxing.

    Reference

    0 讨论(0)
  • 2020-12-30 09:17

    Widening is transforming a primitive or non primitive to a wider type (i.e. one that can hold more bytes).

    Example:

    short -> int
    String -> Object
    

    But, int -> Integer is not widening; it's boxing. Widening has a higher priority than boxing. Also both widening and boxing can't be done together, i.e.

    int -> Long  // cannot be done - both widening and boxing
    
    int -> long  // can be done - only widening
    
    0 讨论(0)
提交回复
热议问题