In an attempt to be as byte pinching as possible(personal goal), I have a question some time on Google has not been able to answer. I did look at some Java documentation to try and resolve the issue but still have not figured it out, so I figured I would ask.

List<List<Sobject>>. Can it be completely written in array notation? At current I am using it in my code as follows and it has been working well for me: List<Sobject[]>. I am returning SOSL query results into this.

When I try something like Sobject[][] sobjArray = null; all I get is errors when trying to save.

I would appreciate some help figuring this out if it's possible. Or if it isn't I would love to get an explanation why it won't ever work.


  • As far as byte pinching, one easy fix is to replace all indentation spacing (the default in the Developer Console and most IDEs) with literal tabs. That can easily shave 20% or more off your total byte count.
    – sfdcfox
    Mar 26, 2019 at 0:22
  • @sfdcfox I actually did this, but out of habit because I like tabs. I didn't realize it saved bytes though. Thanks for letting me know that it does!
    – Genko
    Mar 26, 2019 at 3:54

3 Answers 3


Declaring an array using Type [][] declares it as two-dimensional array and that Salesforce does not allow to declare it that way but only one-dimensional arrays.

References to support this can be found on this documentation (emphasis mine):

Arrays are defined by following the basic type name with the [] characters. These characters must be the terminal portion of the type — arrays of arrays are not allowed

And here on this documentation (emphasis mine):

you can declare a one-dimensional list of primitives or objects by following the data type name with the [] characters

  • I appreciate the links out to documentation, and the explanations. Thank you for answering that. I'll read through those to see if there is any other questions I can get answers to as well.
    – Genko
    Mar 26, 2019 at 3:56

The why is lost to time, I doubt there was a conscience decision. [] is a bit of an oddity in Apex. Apex doesn't have a notion of array so [] is only syntax sugar for list.get(i). When I rewrote the compiler I rewrote the grammar as well, keeping the good as well as the weird. I did make some improvements but looks like this one to be more consistent with Java-like was missed.

Digging into the grammar, I can see that the expression rule uses * hence why you can someListOfList[0][0].

However the rule for types is type ([])?. At cursory glance changing this to type ([])*, should be efficient enough to enable SObject[][] sobject;. I haven't tried to see if ANTLR would have any problem.

There's a bit more for consistent expectation. Apex has special list creator rules which would need to be adjusted as well to support arbitrary depth lists there.

I hope that sheds some light on the history and implementation details.

  • 3
    Nice, my theory was basically on track. FWIW, I don't think we care too much about enhanced multidimensional list constructors (which Apex supports within reason already), just the ability to define a type with multiple dimensions would be incredibly handy (List<List<SObject>> s=[FIND...] probably being the most common use case we'd like to fix). That said, this is incredibly cool info to know. Thanks for your contribution!
    – sfdcfox
    Mar 28, 2019 at 14:28
  • 1
    I agree with what @sfdcfox stated about just wanting to ability to define type with multiple dimensions. Thanks for taking the time to write this out. It was very informative, and really neat to learn.
    – Genko
    Mar 29, 2019 at 17:08
  • By the way I've implemented this into the Apex language, so you can now define a type Sobject[][] sobjectArray. It's been available for a while now, but it slipped through being properly documented. I've filed a doc bug to make it more visible.
    – spags
    Nov 16, 2020 at 23:58

I don't have have a reason "why" it's not allowed, but you're only allowed to use one level of square brackets at a time. This is most likely a limitation of the compiler, and probably related to the same reason why we're not allowed generics; the lexer simply can't handle those combinations. For example, Map<String, Account[]> is legal, and so is Map<String[], String[]>, while List<String[][]> and List<String[]>[] are not. Unfortunately, this is as efficient as you can be in the Apex language. As far as I'm aware, there is no documentation explicitly stating this limitation.

  • This is helpful. I suspect it probably is a limitation of the compiler or something similar. Of course on there documentation they teach people to type using List<Sobject> type notation. Perhaps they didn't expect developers to try to save so many bytes, and just didn't think through implementing that far? Or decided it wasn't necessary? I appreciate the information. It's helpful, and I only knew part of what you mentioned.
    – Genko
    Mar 26, 2019 at 3:58
  • 1
    @Genko Yeah, I don't know the why. I suppose, though, I could shoot out a tweet and see if anyone knows. It'd be interesting to learn about, at least.
    – sfdcfox
    Mar 26, 2019 at 13:17
  • I too would be interested. I say go for it~
    – Genko
    Mar 26, 2019 at 17:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .