A list of funny and tricky Apex examples
Inspired by wtfjs
Boolean b;
if(b!=true) system.debug(‘b is not true’);
if(b!=false) system.debug(‘b is not false’);
See Advanced Apex Programming in Salesforce for explination.
String x = 'Abc';
String y = 'abc';
System.assert(x == y); // passes
System.assertEquals(x, y); // fails
Nothing prevents you from recreating a class with the same name of one that exists in the System
(default) namespace.
public class Database {
public static List<sObject> query(String qry){
System.debug(qry);
return null;
}
}
Running Database.query('foo')
will call our new class (essentially override the Database methods!?)
public class IExist{}
System.assertEquals(IExist.class, IExist.IDont.Class); //passes
Source: Kevin Jones
In their naming conventions:
public class OhGodBees extends Exception{}
//fails: OhGodBees: Classes extending Exception must have a name ending in 'Exception'
Constructors:
public class BeesException extends Exception{
public BeesException(){}
}
//fails: System exception constructor already defined: <Constructor>()
Database.query
is one of many cases where the salesforce "System" namespace doesn't play by it's own rules. It can either return a List<SObject>
or a single SObject
. No Casting required.
Foo__c foo = Database.Query('SELECT Id FROM Foo__c');
List<Foo__c> foos = Database.Query('SELECT Id FROM Foo__c');
Try writing your own method to do this and you'll get a error:
Method already defined: query SObject Database.query(String) from the type Database (7:27)
You can overload arguments, but not return
type.
If you write an If/Else without braces, symbols scoped in the "if" seem to leak into the "else":
if(false)
String a = 'Never going to happen.';
else
a = 'I should not compile';
Worth noting that Java won't even allow you to declare a block scoped variable inside a "braceless IF" as it can never be referenced elsewhere.
Source: Kevin Jones
A Set can be iterated in a for loop:
Set<String> mySet = new Set<String>{'a', 'b'};
for(String s : mySet){}
But it doesn't implement the Iterable interface:
String.join(mySet, ',');
/// fails because Set doesn't implement Iterable
String.join((Iterable<String>) mySet, ',');
/// or does it? This cast succeeds!
- There way to control automatic serialization of object properties (like
[JsonProperty(PropertyName = "FooBar")]
in C#) - There are reserved keywords that you can't use as property names.
Meaning the following cannot be parsed or generated using JSON.deserialize
or JSON.serialize
:
{
"msg": "hello dingus",
"from": "Dr. Dingus"
}
Apperently once upon a time, generics were part of apex. However, they have since been removed (with the exception of system classes (List<>
, Batchable<>
, etc).
Why would you want generics when you're OS has perfectly good Copy & Paste functionality built right into it?
public abstract class ImAbstract {
public String foo;
}
ImAbstract orAmI = (ImAbstract) JSON.deserialize('{"foo":"bar"}', ImAbstract.class);
System.debug(orAmI.foo);
Object x = 42;
System.debug(x instanceOf Integer); // true
System.debug(x instanceOf Long); // true
System.debug(x instanceOf Double); // true
System.debug(x instanceOf Decimal); // true
Source Dainel Barrileger
Thankfully these WTF's have since been fixed by Salesforce. We'll keep them documented for historical purposes (and entertainment).
https://twitter.com/FishOfPrey/status/869381316105588736
https://twitter.com/FishOfPrey/status/1016821563675459585 https://salesforce.stackexchange.com/questions/224490/bug-in-list-contains-for-id-data-type