February 10, 2012

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:


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


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.