Is Apex Casting is not transitive?

Seems as though casting is not transitive in some cases. Consider trying to get an Integer from an SObject number field.

Integer myInt = (Integer) mySObject.get('My_Field__c');

Throws:

System.TypeException: Invalid conversion from runtime type Decimal to Integer

Apparently you need to first cast it to a Decimal, so you can then Cast it to a Integer.

Integer myInt = (Integer)(Decimal) mySObject.get('My_Field__c');

This seems broken to me. Pretty sure casting should be transitive. In other words if. A=B & B=C then A=C.

Or maybe I’m missing something?

Answer

You can’t hop more than one data type per cast; each additional conversion requires another cast.

For example, the following works:

Integer i = (Integer)5.2;

But you can’t write:

Object o = 5.2;
Integer i = (Integer)o;

And you also can’t write:

Integer i = (Integer)(Object)5.2;

Basically, casting a Decimal from an Object reference to an Integer reference is invalid, because it’s not a compatible type.

I wouldn’t call this a “bug” so much as a limitation of the runtime. It’s not documented, so I’m going to ask about it elsewhere.

For now, though, you can safely use Integer.valueOf to get a valid conversion, even if the value is null.


Edit:

The same behavior is observed in Java, so at least it’s consistent.

Runtime Error (Java)

    Object a = 5.2f;
    int b = (int)a;

Valid Code (Java)

    float a = 5.2f;
    int b = (int)a;

It appears that this limitation stems from Java itself, and is not specific to Apex Code.

Attribution
Source : Link , Question Author : NSjonas , Answer Author : sfdcfox

Leave a Comment