I have a basic question about how a list is loaded.

Consider these scenarios:

List<Lead> leadList1 = [SELECT Id FROM Lead];
List<Lead> leadList2 = new List<Lead>();
List<Lead> leadList3;
system.debug(leadList1, leadList2, leadList3);

Let's say that there are no leads in the database. When I go to system.debug these values, leadList1 will error out, leadList2 will be an empty string, and leadList3 will be null.

  • Why does leadList1 not return a NULL value or an empty string?

The results of a query are never null. An individual record at a given index in the results list will also never be null. Individual fields, however, can be null if they contain no data. If there are no leads the database, the first and second example are basically the same, except that one uses a query towards the governor limit.

Also, leadList2 is not an "empty string" (this has a specific meaning, namely an Object that is a String with a size of exactly zero). It simply happens to be rendered as an empty list via String.valueOf for debugging purposes. leadList1 and leadList2, in this example, are equal to each other (leadList1 == leadList2).

Edit: It's also not correct to say that you have a null list. A list is never null. The variable might be null, but a list itself is not null. Null is just null, and also has a specific intrinsic meaning. The following code demonstrates that there's no difference between a variable that's an uninitialized List versus an uninitialized Integer.

List<Lead> leads;
Integer anInt;

System.assertEquals((Object)leads, (Object)anInt);

By casting both variables to a common Object, we can see that null is always null, because it does not have a "type" in the common sense that other objects have types. There's no difference between a "null list" and a "null number".


Your assumption is incorrect and leadList1 will actually be an empty list. You would get an error if you tried:

Lead singleLead = [SELECT Id FROM Lead LIMIT 1];

The reason such an assignment would throw an error is the query has to return exactly one row for it to work. Having zero records or 2+ leads to an error state. However, if a query assigned to a list returns no results, you get back an empty collection.


in addition to the excellent answers by sfdcfox and adrian, you actually want SOQL queries to return lists (empty or otherwise)


A well-written apex class will almost never check for null when dealing with Sobjects or any other collection. Instead, your coding patterns will be of the form:

for (someSobjectType sobj : someListOfSobjects) [
 .. do work. If list is empty, the for loop does nothing

or ..

List<someSobjectType> sobjs = new List<someSobjectType>();
for (someType var : someCollection) {
   sobjs.add(new someSobjectType (
                 fieldA = valA,
                 ... );

insert sobjs; // or update. If list is empty, DML call does nothing

Because Apex is designed to easily work with collections of primitives, custom types, or sobjects; and, since most Apex should be written with bulkification in mind, using the collection idiom and always using collection methods, then the empty vs non-empty case is the same code. No testing for nulls. As long as your collections are initialized, the code shouldn't have to test for null collections.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.