Seems as though casting is not transitive in some cases. Consider trying to get an Integer from an
Integer myInt = (Integer) mySObject.get('My_Field__c');
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?
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.
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.