Win a copy of Mastering Corda: Blockchain for Java Developers this week in the Cloud/Virtualization forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Bear Bibeault
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Stephan van Hulst
  • Jj Roberts
  • Carey Brown
Bartenders:
  • salvin francis
  • Frits Walraven
  • Piet Souris

Array Declaration - Would anyone sane ever do this in a real program for some reason?

 
Ranch Foreman
Posts: 175
8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi:

First off, I know the certification exams and mock tests that prepare one for them are very concerned with what is legal and will compile, rather than what is a good idea.

It is completely legal to wear boots on your hands and shorts on your head, as long as you have shoes and a shirt on.

I got a mock exam question wrong today because it turns out the following are legal array definitions.



Now, I have been programming a long time, and I am used to code where we might make a zero length array because some API requires us to pass an array and we have no values to put in it, tho varargs feature makes that less common in modern Java, if I am correct.  

I memorized today that the preferred way to get a cloned array out of a list is:

A little awkward, but fine, I'll memorize the idiom, for certification and beyond.

I definitely have totally memorized that the following is legal (we will assign values to the array of arrays further on):
Object[][] weirdTwo = new Object[5][];

and that the following is quite illegal, as it is taken to have no clear meaning:
Object[][] weirdTwo = new Object[][2];

I thought I was done with the complex topic of different legal ways to declare Multi-dimensional arrays in Java, then I got hit with the question that made me confront that:

is legal.

Is there any reason someone would ever do that in real life besides they had too much LSD in their beer?  I might be able to see how code where each dimension was based on some variable that could be 0, and we don't want to throw a fatal exception just because numberOfCars is zero, say.  Is it just that?

I just can't see how code farther down would ever make valid use of the [2] or the [5] dimensions, or tell what code the compiler is even generating here.

Thinking about it some more, I guess if we need to pass zero or more strings followed by zero or more ints to a method, varargs can't help us, we will wind up passing a zero length array.
But not for the nutty multi-dimensional arrays I just found out were legal.

Thanks,
Jesse
 
Marshal
Posts: 71699
312
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesse Silverman wrote:. . . I am used to code where we might make a zero length array because some API requires us to pass an array and we have no values to put in it

The 0‑length array is used to denote that there were no values to insert.

tho varargs feature makes that less common in modern Java. . . .

No, you can create a 0‑length array from varargs.

Is there any reason someone would ever do that in real life besides they had too much LSD in their beer?

Line 2 declares that it has an array containing space for any non‑negative numbers of 2‑element int[]s. In the case of line 2, you are initialising it for zero of such arrays, Just as you can declare you want zero names if you have a middleNames array and somebody doesn't have a middle name. An array can have any component type, including arrays, so, as I hadn't realised before, your declarations are legal.
 
Jesse Silverman
Ranch Foreman
Posts: 175
8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your code example with varargs reinforced what I was trying to say.

In old Java, and in C and in other languages, if we want to take 0 or more parameters of some type, we would likely bundle them all up into an array and pass that as one of the parameters.

When I learned the nifty... varargs in Java 5, I prematurely decided I was done with that, because we can just have calls like:

takeSomeInts( 5, 2, 8 );
takeSomeInts( 7 );
and now:
takeSomeInts( );

But we can only pull that varargs trick once per parameter list.

If we want to pass zero or more ints AND zero or more Strings to the same method, we are back to packing 'em into an Array.

I am still unpacking your answer about the primary point, i.e. whether [2][0][3] or [0][9] makes any sense in a new -- it still seems whacked to me.
I would be okay if the following index was: [] instead of a fixed number.
 
Campbell Ritchie
Marshal
Posts: 71699
312
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Remember you can change the array lengths (not indices) to the right of the 0 because components of an array of arrays can always be reassigned. And they may have different lengths.
Remember that varargs packs the elements into an array. And yes, you can declare a method...and that should permit you to pass new String[0], new int[0] as arguments.
 
Rancher
Posts: 4785
50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesse Silverman wrote:
I memorized today that the preferred way to get a cloned array out of a list is:



Not sure that's necessarily the preferred way.
toArray() uses the supplied array if it's long enough to fit the contents of the list, otherwise it creates a new one of the correct size.
So with the above it will essentially create an additional object to then fill whereas:

will use the supplied array.

I mean, there's not exactly much in it, but one creates an object that's not used for anything other than figuring what type to return, and the other just uses the given object.
 
Sheriff
Posts: 22055
113
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Dave Tolls wrote:

Jesse Silverman wrote:
I memorized today that the preferred way to get a cloned array out of a list is:



Not sure that's necessarily the preferred way.
toArray() uses the supplied array if it's long enough to fit the contents of the list, otherwise it creates a new one of the correct size.
So with the above it will essentially create an additional object to then fill whereas:

will use the supplied array.

I mean, there's not exactly much in it, but one creates an object that's not used for anything other than figuring what type to return, and the other just uses the given object.


I also prefer to pass pre-sized arrays, but I've read somewhere that it's actually better to pass empty arrays. A quick search found another source: https://github.com/pinpoint-apm/pinpoint/issues/4138.

Of course, in Java 11 and later the solution is obviously to not use this method at all, but instead use the new toArray method:

 
Jesse Silverman
Ranch Foreman
Posts: 175
8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Rob.  I learned some good stuff as a result of posting my gripe, even if I am unsure of the answer to my original question.

You certainly are allowed to create multi-dimensional arrays with the size of the first dimension or some intermediate dimensions as 0, I won't ever forget that again.

Is there ever actually a good reason to do it in real life, tho?

I was thinking that if the size for each dimension was based on an input parameter or variable, you would have more orthogonal code not to have to treat 0 as a special case.
Like if the size for the 2nd dimension was numAxles and this particular vehicle was a boat.  I still feel weirded out by seeing very definite sizes after a [0] but that's probably because the example had hard-coded compile-time constants.  The ability is there for when they are variables, but doesn't get taken away when they are constants...
That is definitely a good general rule "Don't artificially force application developers to treat having zero of something as a special case."

I think if that's all this is, there's nothing more to see here and I'll move along (having found a better way to get a nice shiny new array out of my list in Java 11+, thanks).
 
Campbell Ritchie
Marshal
Posts: 71699
312
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Spoor wrote:. . . new toArray method: . . .

Is it this method, Rob?
 
Saloon Keeper
Posts: 12613
273
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I feel that everybody is missing the point of Jesse's original question.

The question is, why would you ever want to initialize an array with dimensions [3][0][5] when using the dimensions [3][0][0] or [3][0][] will yield the same array?

To answer your question Jesse, there's no good reason. As a matter of fact, when you use JShell to initialize an array variable with new Object[3][0][5] it wield display the following result:

In short, if one of the dimensions of your array has length zero, there's no point in specifying a length for the next dimension at all, not even 0.
 
Campbell Ritchie
Marshal
Posts: 71699
312
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
...but the question arose from a cert exam revision book question. As you said, Stephan, the fifth dimension last dimension is ignored, which means it can have any size. So the code is “legal”, which is what the cert question is asking. You can initialise the array as new int[2147483647][0][2147483647] or new int[2147483647][0][2147483647] and reassign it to a sensible non‑zero size later (possibly in the catch (OutOfMemoryError ex) ... ).
But you and JS are correct: any dimensions following a 0 are pointless.
 
Rob Spoor
Sheriff
Posts: 22055
113
Eclipse IDE Spring VI Editor Chrome Java Ubuntu Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

Rob Spoor wrote:. . . new toArray method: . . .

Is it this method, Rob?


It is.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic