Default Namespaces in Apex

Your org has a namespace, whether you are doing packaging or not. Here is an explanation of that namespace, and how it is used in Apex.

The following is a primer on default namespaces in every org and how they are used in Apex.

First, here’s a fun “trick” you can play on yourself!

Step 1

Run this snippet in the execute anonymous window:

sObject[] acct = Database.query(‘Select id, Name from Account Limit 1’);
system.debug(acct[0].get('name'));

Step 2

Create this class in your org:

    public class Database {
        public static String query() {
            return 'wherefore art thou namespace?';
        }
    }

Step 3

Run the same snippet from Step 1 again.

This time you get an error – method does not exist or incorrect signature. What happened? To illustrate, let’s try one more step.

Step 4

Run this modified snippet:

sObject[] acct = System.Database.query(‘Select id, Name from Account Limit 1’);
system.debug(acct[0].get('name'));

Notice the slight difference? In this last step, we’re explicitly referencing the System namespace, which we typically don’t need to do. By making this minor change, we again get access to the query method as we expect.

What is at play here is that Apex offers you two “default” namespaces. Your org gets an implicit namespace, and the System namespace is provided to all orgs. By “default”, I mean you do not need to explicitly identify these namespaces when making a function call. In this example, the two namespaces are colliding, in that we have a “Database” class in each.

Every org has its own org namespace, which is where all of your custom Apex classes live. You don’t need to know the actual name for your org’s namespace unless you are going to do packaging and distribution, so you can just pretend it has no name at all. You can conveniently refer to any custom classes directly, without any prefix:

//this
MyClass m = new MyClass();
//not this
//MyOrgNamespace.MyClass m = new MyOrgNamespace.MyClass();

Apex also provides the System namespace to all orgs, which is where all of the standard features live. This includes things like the Math methods, the HTTPRequest class, the Test methods, and the Database methods. Since these are common to all orgs, you are not required to prefix your calls to things in the System namespace with “System.”, but you can explicitly do so whenever you feel like enhancing the readability of your code. This is also intended to be more convenient for the programmer … think of it like automatically having an “import System.*” statement in every Apex context.

You have quite possibly never been aware of these namespaces, since there is rarely any interaction between them. Until I told you to play a trick on yourself in this post, you probably wouldn’t have thought to name a class “Database”. Thus, when there is a conflict, like in the example here, you could end up confused.

Your Org’s Namespace has Priority Over the System Namespace

In this example, the compiler first looks to see if your org has a “Database” class, and if so, it uses that. The compiler next looks in the System namespace for a “Database” class. Thus, you can accidentally (or intentionally) override a System namespace class!

You can use a class in both your own namespace and the system namespace in the same org. By explicitly using the “System.” prefix, you tell the compiler that you’re looking for the functionality in the System namespace, rather than your custom class. This allows you to create a class named “Database” for your own purposes, while still having access to the System.Database methods. Your own class is accessed without prefix, and the System class is explicitly referenced:

Database d = new Database();  //your class, without prefix
System.debug(d.query());  //'wherefore art thou namespace?'
sObject[] accts = System.Database.query('Select id, Name from Account');  //explicit prefix, queries using the system database method

I have encountered several situations where a developer created a class named “Test”, unaware they would block the system Test methods (e.g. Test.startTest()). As you can imagine, this has created some confusion for some unsuspecting programmers when they went to run tests!  This could be solved by renaming the custom Test class, or by calling System.Test.startTest() across the org.

 

Now you know more, and you are a stronger developer.  Happy Coding!

Published
August 29, 2012

Leave your comments...

Default Namespaces in Apex