Press ESC to close

Tip: Using Decimal class with Strings in Apex

Today I came across an interesting problem that reminded me of my Java days. A piece of Apex code written by some other developer was broken, when I did my fixes.

Here is some background about the broken code, lets say the file name is “ScaryMovie.cls

  • It tries to query a Number(18, 0) field from Sobject, lets say sobject is Mock__c, and number field is “Counter__c

  • Appends the number field to a String to create a URL, for ex

    Mock__c mock = [Select Counter__c from Mock__c where Name = 'Demo'];
    String url = 'http://mycooldomain.com/'+ mock.counter__c;
    System.debug ('Generated URL :' + url);

The apex class was an old class, i.e. of 16.0 API version. When executed, with Counter__c value of “1.0”, this code generates URL as shown below:

http://mycooldomain.com/1.0

How things got broken ?

For my fixes I was using some newer features of Apex, and have to upgrade the API version of class to latest one. This API version change broke the previously working code !! The URL is now generating as

 http://mycooldomain.com/1

Any guess what could be the reason of this show stopper ?

Why this happened ?

Update : Thanks to @rich_unger for suggesting the correct cause of the problem. I was previously thinking the problem was because of change in toString() method implementation in v16.0 to v23.0 of API. But its Double class that is used in v16 API, that’s been upgraded to Decimal class in later versions for more precision. 

So to again get back to the same Double in Apex, we can change the code as shown below:

Mock__c mock = [Select Counter__c from Mock__c where Name = 'Demo'];
Double dblValue = mock.Counter__c .doubleValue();
String url = 'http://mycooldomain.com/'+ dblValue;
System.debug ('Generated URL :' + url);

Ideal practice

Instead of directly appending any queried number field to the String, try storing it as a specific Type(Decimal) in a local variable. This will save you from any accidental code API version upgrade from breaking the existing code.

Your feedback ?

Love to hear back.

Comments (5)

  • Anonymoussays:

    February 10, 2012 at 4:06 pm

    Also, your analysis of the root cause is slightly off. The toString didn't change. The apex type of an sobject number field did. In version 16, it was a double. In later versions we represented them as decimals for greater precision.

  • Anonymoussays:

    February 10, 2012 at 5:53 pm

    Thanks a lot @Rich for your guidance here, today was a bad day for me, and you're correct I checked again about the usage of Double in Apex in v 16.0, thats the real root cause. I'm updating the post to correct it. Yes I was relying on Doube's toString(), I end up relying toString() to something that can't be further broken, we don't have boxing/unboxing in Apex to have “int” vs “Integer” both in place 🙂

  • Anonymoussays:

    February 11, 2012 at 12:56 pm

    Sure Rich, I understand the API version thing. But the Java soul inside me, stops me from using toString() :)One request, I always wanted to know how does this API versioning works behind the scenes. It would be really nice of you, if you can blog this with the world.

Leave a Reply

%d bloggers like this: