Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why calling some functions of the Object class, on a primitive type instance, need boxing?

I have discovered that if i run following lines of code.

int i = 7;
i.GetHashCode(); //where GetHashCode() is the derived
                 //function from System.Object

No boxing is done, but if i call i.GetType() (another derived function from System.Object) in place of GetHashCode(), a boxing will be required to call GetType(), Why its not possible to call GetType() on primitive type instance directly, without boxing, while its possible to call GetHashCode() without boxing ?

like image 861
waheed Avatar asked Feb 01 '10 19:02

waheed


People also ask

What is the difference between primitive type and object type?

Primitives are passed by value, i.e. a copy of the primitive itself is passed. Whereas for objects, the copy of the reference is passed, not the object itself. Primitives are independent data types, i.e. there does not exist a hierarchy/super class for them. Whereas every Object is descendent of class "Object".

Why We Need primitive data types in Java?

The main reason primitive data type are there because, creating object, allocating heap is too costly and there is a performance penalty for it. As you may know primitive data types like int, float etc are most used, so making them as Objects would have been huge performance hit.

How do you use primitive data types as objects?

An object of Boolean is created. In the above example, we have created variables of primitive types ( int , double , and boolean ). Here, we have used the valueOf() method of the Wrapper class ( Integer , Double , and Boolean ) to convert the primitive types to the objects.

What is the difference between primitive and object data types in Java?

Primitive data types are predefined. Object data types are user-defined. These data types are held in a stack. In these data types, the original object is kept in the heap, and the reference variable is kept in the stack.


2 Answers

The key here is that GetType() is not virtual and cannot be overridden. Since a struct is effectively sealed, methods cannot be overridden any more than the struct, so the runtime and compiler can treat struct methods that have been overridden as static calls.

If you write a struct (rare) you should override all the methods like ToString(), Equals(), GetHashCode() for exactly this reason. If you don't it must box. However, GetType() cannot be overridden, thus needs boxing.

This actually leads to some odd edge-cases with Nullable<T> and boxing, since an empty Nullable<T> boxes to null, so:

int i = obj.GetHashCode(); // fine
Type t = obj.GetType(); // boom
like image 195
Marc Gravell Avatar answered Nov 15 '22 16:11

Marc Gravell


I think the reason is that GetHashCode is implemented on System.Int32 directly, you call System.Int32::GetHashCode(). No need to box if you call a known member function on a value type.

like image 28
Arve Avatar answered Nov 15 '22 18:11

Arve