String.valueOf
returns Blob[X]
for Blob values. I believe it does it this way because System.debug
internally uses String.valueOf
, and debugging a potentially non-Unicode stream into a Unicode String could break things. In other words, you can't reliably use String.valueOf
unless you can also use it in System.debug
and get the output you expect. String.valueOf
is always safe to use on a Blob, but Blob.toString
may result in an exception if the contents are not a Unicode String.
Let's go with some examples to show how other standard and custom objects behave:
String.valueOf(JSON.createParser('[]'));
// JSONParser:[delegate=common.apex.json.ApexJsonParser@7cde3f62]
String.valueOf(Crypto.generateAesKey(128));
// Blob[16]
String.valueOf([SELECT Id FROM Account LIMIT 1]);
// (Account:{Id=001..., RecordTypeId=012...})
String.valueOf(new MyClassWithoutToString());
// or //
new MyClassWithoutToString().toString();
// MyClasswithoutTostring:[key1=value1, key2=value2]
String.valueOf(new MyClassWithToString());
// Hello There. I work correctly because I have an overridden toString.
String.valueOf(Date.today()); Date.today().format()
// 2016-02-10 // 2/10/2016
Database.getQueryLocator([SELECT Id FROM Account LIMIT 1])
// Database.QueryLocator[Query=SELECT Id FROM Account LIMIT 1]
String.valueOf(Database.setSavepoint());
// SavepointValue0
String.valueOf(new Component.MyCustomComponent());
// *** Crashes and produces no logs ***
As you can see, you can never quite be sure what you're going to get out of it, unless you're using one of the concrete types listed in the documentation, which is currently: Date, DateTime, Decimal, Integer, and Long.
It does say that it supports "Object" generically, but generally speaking, you'll get the "debug safe" version of a string if you do so, which means it will probably be the wrong value.