Search code examples
javac#boxingunboxing

In this example, is boxing used when unboxing is needed?


I have some difficulty understanding the following part from Programming Language Pragmatics, by Scott

C# and more recent versions of Java perform automatic boxing and unboxing operations that avoid the wrapper syntax in many cases:

ht.put(13, 31);
int m = (Integer) ht.get(13);

Here the Java compiler creates hidden Integer objects to hold the values 13 and 31, so they may be passed to put as references. The Integer cast on the return value is still needed, to make sure that the hash table entry for 13 is really an integer and not, say, a floating-point number or string. Generics, which we will consider in Section 7.3.1, allow the programmer to declare a table containing only integers. In Java, this would eliminate the need to cast the return value. In C#, it would eliminate the need for boxing.

  1. I was wondering what it means by "The Integer cast on the return value is still needed, to make sure that the hash table entry for 13 is really an integer and not, say, a floating-point number or string"? Note that this is in Java.

    In int m = (Integer) ht.get(13);, does it use boxing (by (Integer)) during unboxing (assignment to int)?

    Specifically, does (integer) convert its operand to an object of the Integer class? But its operand ht.get(13) is already an Integer object, and now the assignment expects a value of builtin type int. So don't we need a conversion from Integer to int here?

  2. How does generics "eliminate the need to cast the return value" in Java ?

    In C#, how would it "eliminate the need for boxing"?

Thanks.


Solution

    1. Without specifying generic types on the declaration of ht, the return type of get() is Object, so you have to cast that to Integer. Java will then auto-unbox that to int.

      The cast itself doesn't do any conversion. It just tells the compiler to treat the Object as an Integer. If the object is not in fact an Integer, a ClassCastException will occur at runtime.

    2. With use of generic types, ht would likely be declared as Map<Integer, Integer>, so get() would return Integer, and cast would be redundant.

      In C#, it could be declared as the Java equivalent of Map<int, int>. Java doesn't support primitive types as generic type arguments, so that syntax would be illegal.