Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Widening and Boxing Java primitives

Widening and Boxing Java primitives.

I know it is not possible to widen a wrapper class from one to another as they are not from the same inheritence tree. Why though is it not possible to widen a primitive to another primitive type and autobox the widened primitive?

Given that a byte argument can be passed to a method that expects an int, why cant the byte in the following example be widened to an int and then boxed to an Integer?

class ScjpTest{
    static void goInteger(Integer x){
        System.out.println("Going with an Integer");
    }

    static void goInt(int x){
        System.out.println("Going with an int");
    }

    public static void main(String args[]){
        byte b = 5;
        goInt(b);
        goInteger(b);
    }
}

In the above example, goInt(b) is accepted by the compiler but goInteger(b) is rejected.

like image 243
ziggy Avatar asked Aug 10 '11 16:08

ziggy


People also ask

What is boxed primitive in Java?

In Java, when primitive values are boxed into a wrapper object, certain values (any boolean, any byte, any char from 0 to 127, and any short or int between -128 and 127) are interned, and any two boxing conversions of one of these values are guaranteed to result in the same object.

What is widening in Java?

Widening − Converting a lower datatype to a higher datatype is known as widening. In this case the casting/conversion is done automatically therefore, it is known as implicit type casting. In this case both datatypes should be compatible with each other.

Is boxing and Autoboxing same in Java?

Boxing is the mechanism (ie, from int to Integer ); autoboxing is the feature of the compiler by which it generates boxing code for you.

What is Autoboxing and boxing in Java?

Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing.


4 Answers

Short answer

The java language only supports some level of carelessness.

Longer answer

I believe that autoboxing was added to support developer carelessness. Specifically in situations like this: "I need an Integer as a parmeter to the method I want to call, but I have an int. Somehow, new Integer(int) never pops into my head. Instead, I'll just send an int and the java compiler will do the new Integer() call for me. Thanks java carelessness support group!"

The folks designing autoboxing were willing to support 1 level of carelessness (int => Integer and back), but were not willing to support auto casting of smaller primitive types to larger primitive types in conjunction with automatic creation and extration from primitive type wrapper classes. I suspect the descision matrix for this would be somewhat larger than the decision matrix for the current autoboxing scheme.

like image 62
DwB Avatar answered Oct 19 '22 10:10

DwB


Why? Because boxing / autoboxing is only some compiler sugar and not a new type system. It's badly designed and causes trouble at least as often as it simplifies things.

But here are some workarounds for your compile error:

goInteger((int) b);

// these are equivalent
goInteger(((Byte) b).intValue());
goInteger(Byte.valueOf(b).intValue());
like image 36
Sean Patrick Floyd Avatar answered Oct 19 '22 11:10

Sean Patrick Floyd


If we allow too many magic conversions, it'll get very confusing.

The existing conversion rules are already more than people care to understand. Even the language spec got it wrong! See this funny example Java casting: is the compiler wrong, or is the language spec wrong, or am I wrong?

like image 29
irreputable Avatar answered Oct 19 '22 10:10

irreputable


In Java, Boxing + Widening is allowed, but not Widening + Boxing.. For goInteger to be accepted, first widening of primitive datatype (byte -> int) is required, which ok and then Boxing is required (int -> Integer). Please find the 5 golden ruled of Widening, Boxing and Vararg:

  1. Primitive Widening > Boxing > Varargs.
  2. Widening and Boxing (WB) not allowed.
  3. Boxing and Widening (BW) allowed.
  4. While overloading, Widening + vararg and Boxing + vararg can only be used in a mutually exclusive manner i.e. not together.
  5. Widening between wrapper classes not allowed

I hope this will help you. With regards, Sudipta Deb.

like image 39
Sudipta Deb Avatar answered Oct 19 '22 11:10

Sudipta Deb