The application supports the use of namespace prefixes. Namespace prefixes are used in managed Force.com AppExchange packages to differentiate custom object and field names from those in use by other organizations. After a developer registers a globally unique namespace prefix and registers it with AppExchange registry, external references to custom object and field names in the developer's managed packages take on the following long format:
namespace_prefix__obj_or_field_name__c
Because these fully-qualified names can be onerous to update in working SOQL statements, SOSL statements, and Apex once a class is marked as “managed,” Apex supports a default namespace for schema names. When looking at identifiers, the parser considers the namespace of the current object and then assumes that it is the namespace of all other objects and fields unless otherwise specified. Consequently, a stored class should refer to custom object and field names directly (using obj_or_field_name__c) for those objects that are defined within its same application namespace.
To invoke a method that is defined in a managed package, Apex allows fully-qualified identifiers of the form:
namespace_prefix.class.method(args)
Use the special namespace System to disambiguate the built-in static classes from any user-defined ones (for example, System.System.debug()).
Without the System namespace prefix, system static class names such as Math and System can be overridden by user-defined classes with the same name, as outlined below.
However, with class variables Apex also uses dot notation to reference member variables. Those member variables might refer to other class instances, or they might refer to an sObject which has its own dot notation rules to refer to field names (possibly navigating foreign keys).
Once you enter an sObject field in the expression, the remainder of the expression stays within the sObject domain, that is, sObject fields cannot refer back to Apex expressions.
For instance, if you have the following class:
public class c { c1 c1 = new c1(); class c1 { c2 c2; } class c2 { Account a; } }
Then the following expressions are all legal:
c.c1.c2.a.name c.c1.c2.a.owner.lastName.toLowerCase() c.c1.c2.a.tasks c.c1.c2.a.contacts.size()
For the type T1.T2 this could mean an inner type T2 in a top-level class T1, or it could mean a top-level class T2 in the namespace T1 (in that order of precedence).