21 ms·
Inside the JVM: Arrays and how they differ from other objects
- awelxtr 3y ago> (Note that the comma after the last value is accepted in Java and won’t cause an error.) Why have I been 15 years programming in Java and I discovered this today? On a more serious note, I prefer this kinds of posts to the traditional "Look at this shiny new thing" because without fundamental stuff the next big thing can't be built and normally this information makes you a slightly better programmer.
- vbezhenar 3y agoI believe that comma thing was added recently.
- awelxtr 3y agoYup, as recent as 1996: "A trailing comma may appear after the last expression in an array initializer and is ignored" https://titanium.cs.berkeley.edu/doc/java-langspec-1.0/10.doc.html#11358 https://titanium.cs.berkeley.edu/doc/java-langspec-1.0/10.do...
- twic 3y agoThe comma thing is inherited from C and has always been there. Newer bits of array-like syntax, like varargs and array literals in annotations, do not allow trailing commas.
- rightbyte 3y agoI have this feeling the C comma operator was a accident from making function calls work in the beginning. After doing some hobby languages of my own I have come to realize many features are kinda automatic and accidental when writing languages, in a way other programming almost never is.
- ghusbands 3y agoYou may be thinking of javascript, which has added various kinds of trailing comma over the years, though arrays had them from the start. See https://stackoverflow.com/a/67793166 https://stackoverflow.com/a/67793166
- cxr 3y ago[flagged]
- vbezhenar 3y agoDid you ask yourself this question before you wrote this comment?
- cxr 3y agoTo answer your question: no, I didn't. It doesn't make sense to—I'm not here saying anything like, "I believe it's because X" without knowing whether X is true or not. If you think otherwise, explain how. (I have now answered your question. If you respond, how about doing so in the form of an answer to mine—and not evading it with another question?)
- vbezhenar 3y agoI bothered to comment because I write Java for 15 years and I thought that my knowledge was relevant to this topic. I’m not going to check every my comment with reference documentation. In this particular case my memory failed me and I was quickly corrected and downvoted, so no harm was done, I guess, other than few people spending few minutes, for which I feel sorry, but not very much.
- dtech 3y agoLikely because it's inconsistent with all other parts of the language where trailing commas are not allowed
- e3bc54b2 3y agohey now, Enum allows trailing comma before semicolon, and ever since discovering that, I've been putting extra comma at the end of last Enum value and semicolon on new line. Why? Because whenever there's a new value added, git diff shows single line change :)
- nayuki 3y agoIndeed. Whereas JavaScript and Python even allow a trailing comma in function parameters: function foo(x,) {} def foo(x,): pass Before anyone questions why anyone would do this, it's for putting arguments (or array elements) on separate lines: function foo( a, b, c, ) {}
- CobrastanJorji 3y agoAlthough be careful with that in Python because there are other situations where (x) and (x,) are both legal but mean very different things.
- devonkim 3y agoIn Python the comma acts as a tuple creation operator inside parentheses with no other context like function invocation. Also, last I remember in JS a trailing comma meant the creation of an extra array element that’s null so I became conditioned to only use trailing commas for separators in languages where it’s consistent and specified very explicitly like in HCL
- n2d4 3y agoTrailing commas in JS don't do that, but having more commas than values does. (eg. [1,,].length === 2)
- agilob 3y agoRead a book on preparing for Java SE Certification, the exam is full of questions about things like this
- Pannoniae 3y agoWhat are the advantages of representing multidimensional arrays with pointers to arrays instead of a "flat" version where everything is stored contiguously and access is simply pointer arithmetic? EDIT: For the JVM, not manually. I'm asking about the internal representation, not a manual flattening by the user.
- awelxtr 3y agoMaintenance, probably. Puting data in a structure that mirrors the real thing normally helps when trying to understand it
- Pannoniae 3y agoNo, I mean for the JVM.... the interface could remain the same but the pointer indirections could be avoided. I don't see the downsides, that's why I'm asking.
- tralarpa 3y agoI guess it was just to simplify the original specification of the JVM (if two dimensional arrays are just arrays of arrays, you don't need special instructions for them). I can also imagine that the original JVM designers did not expect JIT compilers to one day become so good that the performance difference becomes relevant.
- samus 3y agoBut there is actually a special bytecode instruction to create multidimensional arrays: MULTIANEWARRAY. My suspicion is that it allows a sufficiently sophisticated JVM to allocate all the memory required at once such that all of it is contiguous. Also, the performance impact has nothing to do with the JIT. It follows from how indexes in contiguous vs. ragged arrays are computed. The JIT can't do much in this case apart from providing speedup by a constant factor. (Actually, it could do more if Java had true multidimensional arrays)
- alex3305 3y agoIn my experience, just a little bit of insider knowledge goes a long ways to making better code. Arrays are fun things, especially when you do a deep dive into the System.arraycopy() function. But the same goes for all Collections in Java. For instance, most of them have a default size (mostly 10), and growing them is a costly operation. So knowing beforehand how large your collection can or may be, can benefit code. I could use this effectively when working with large document XML parsing. I recommend everyone that uses a managed language (Java, C# or others) to at least get a basic understanding of these fundamentals. And also know which collection type to use when.
- dkwr 3y agoI agree. Understanding the inner working of languages and their runtimes is IMHO what gets you one step closer to a senior. Luckily, I had in my young career few seniors in the team who knew a lot about Java and shared their knowledge about the behavior.
- pjmlp 3y agoI cringe every single time I see a for loop for what System.arraycopy () has been providing since early days. For better or worse, it shows me that the author isn't that into Java.
- gdprrrr 3y agoI cannot for my life remember the argument order, so I write the manual code and let IntelliJ convert it.
- SeanLuke 3y ago> Another curiosity of Java arrays is that they can have a size of zero. > This code will not result in an error message. This surprising feature is used primarily by code generators, which might create an array and then discover there are no values to place in it. What? How can someone at Oracle have written this? Zero-length arrays are used all the time when you call a function asking for an array of "the latest stuff" and it needs to be an array, not an ArrayList say (maybe it's an array of bytes). If there's no stuff, you get a zero-length array of course. The myriad foo.toArray(...) functions in Java's library do this for example.
- adrianmsmith 3y agoRight, and > create an array and then discover there are no values to place in it. I mean you can't change the size of an array after you've created it, so if you create an array with a certain size intending to put values in it, then discover there aren't any values, you've still got a non-zero size array...
- keyle 3y agoThis choice probably pre-dates Oracle?
- deleted 3y ago[deleted]
- andrewbinstock 3y agoAuthor here. Zero-length arrays are used in the narrow domain you mention. but they are rare in bread-and-butter Java programming. Given some of the other comments on this page, you can see that this aspect is new to multiple readers. And in my experience speaking to Java devs, the reaction of surprise is far more common than "of course, I use them."
- eternalvoyage 3y agoThings I learned by reading this post * Java arrays can have 0 dimensions * When declaring arrays, trailing comma is allowed after the last element * In multi-dimensional arrays, only the last dimension contains actual values. Other dimensions are just pointers to arrays. Good read.
- SeanLuke 3y agoArrays cannot have zero dimensions. They can have zero-sized dimensions.
- adrianmsmith 3y ago> Java arrays can have 0 dimensions The way you've phrased it is a bit ambiguous. Having 0 dimension sounds like x = new int[7][5]; // 2 dimensions y = new int[9]; // 1 dimension z = new int; // no dimensions, not an array, not allowed The phrasing you mean is "dimensions can have zero size".
- eternalvoyage 3y agoThanks for the clarification.
- xdavidliu 3y agoUnfortunately the article author uses the exact same terminology: > (It’s somewhat counterintuitive that the zero dimension is not the first one in the array.)
- Izkata 3y agoNo, this is a quirk of the English language that I'm not sure how to describe generally. Best I can do: "Dimensions" plural agrees with "zero" as a count, so that reads as "the count of dimensions is zero". But they used singular "dimension" with "the" which treats "zero" as an adjective. It means "the dimension that is zero".
- 3y ago
- SeanLuke 3y agoI was pretty disappointed that, for a blog called "Inside the JVM", very little in the blog entry discussed goings on inside the JVM. For example, when does the JVM typically optimize away bounds or null checks? How are arrays of booleans packed and what is their efficiency compared to arrays of bytes or words?
- pjmlp 3y agoFor that you need an Inside Hotspot, Inside OpenJ9, Inside GraalVM, Inside Azul, Inside ART, Inside microEJ, Inside PTC, Inside JamaicaVM, Inside.... Otherwise is like trying to discuss what does a C compiler do, when only looking through the lens of the C abstract machine in ISO C.
- SeanLuke 3y agoThis is an Oracle blog, and it's called "Inside the JVM". What VMs do Oracle build besides Hotspot and its ilk?
- stefs 3y agoas far as i know, graalvm is also an oracle project
- aardvark179 3y agoGraalVM, the JVM inside various database products, historically the embedded VMs, and maybe a few more I’ve forgotten. :-)
- brabel 3y agoAs far as I know, all those distributions use OpenJDK for that kind of stuff and don't really do much more than apply a few patches here and there, not change stuff like how the JVM packs bytes in memory. Would be happy to be proven wrong.
- pjmlp 3y agoIBM OpenJ9 uses a mix of OpenJDK and their J9 toolchain. Azul uses parts of OpenJDK, alongside their JIT Falcon infrastructure. Microsoft OpenJDK based distribution has better escape analysis than regular one, although OpenJDK 22 should have those improvements merged. And no, not all of them use OpenJDk, it is an urban myth, as usual.
- Izmaki 3y agoI was honestly hoping for a little more considering the title is "Inside the JVM" and not "Basic data structures in Java". Oh well...
- xdavidliu 3y ago> (It’s somewhat counterintuitive that the zero dimension is not the first one in the array.) I must've read this sentence at least 7 times, but don't understand what this means. Can anyone illuminate?
- layer8 3y agoThe article is very confused in general about multidimensional arrays (which are really just arrays of array references in Java). It’s badly written and IMO doesn’t deserve to be on the HN front page. The author seems to have expectations that Java multidimensional arrays violate, and seems to assume the reader would also have those expectations, but they just seem confused to me. Except for TFA’s mention of the bytecode instructions and trailing comma, the classic tutorial article is much better: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html https://docs.oracle.com/javase/tutorial/java/nutsandbolts/ar...
- layer8 3y agoTo elaborate further, consider this quote from TFA: “For example, strangePoints = new int[3][4][0][2] In this declaration, all dimensions after the zero-size dimension are ignored. So, the result of this declaration is equivalent to a two-dimensional array of ints.” This is just plain wrong. It’s a four-dimensional array of ints, just one that cannot contain more than zero ints, because one of the dimensions is zero. To illustrate, int[][] a = strangePoints[0][0]; will typecheck while int b = strangePoints[0][0]; will not (which however it should if the author’s claim that strangePoints is a two-dimensional array of ints was true). The talk about Object having no size() method and arrays having therefore a length field is also confused. Arrays have distinct types (and classes, in the sense of getClass()), and therefore could very well have a size() method. It’s merely a stylistic choice of Java that they opted for the simpler .length syntax. The article is so misguided as to be harmful.
- deleted 3y ago[deleted]
- 3y ago
- TOGoS 3y agotl;dr: Arrays have some special opcodes dedicated to them, and otherwise are completely unsurprising, unless you are an ancient Roman, or Andrew Brinstock, who can't wrap his head around the concept of zero and thinks it should be special somehow. And nobody can give a good reason why String#length(), Array#length, and Collection#size() are all spelled differently, but if pressed, they'll use 'special bytecodes!' as an excuse.
- jbverschoor 3y agoArray is a fixed size memory, therefore it’s unnecessary to invoke a method A string has a length, because it counts the number of characters, which can have different sizes. Both arrays and strings represent a 1-dimensional string or away of things. Collections have sizes, because collections are more generic. Would a binary tree have a length? Maybe.. but it’s ambiguous and in most cases not correct
- TOGoS 3y agoUh-huh. And yet they can (according to the article) turn .length into a special opcode, even though it looks like any other property access. So the Java compiler could just as easily see size() being called on what it knows is an array and turn that into a special opcode. We could argue about the semantic differences between length-as-in-number-of-characters and size-as-in-bytes, but for most purposes, i.e. when any of String, char[], or List<Character> would be logically equivalent, there's no technical reason for having different APIs for what are essentially different implementations of the same thing. Like when Rasmus couldn't stick to a naming convention for PHP functions, and it turned out to be because he couldn't be bothered to write a decent hash function. So everyone who uses the language from now to forever has to memorize this inconsistent naming scheme because the language designers couldn't get their shit together. Yeah, I get it; sometimes it's hard to foresee these things from the beginning. But it annoys me when people make up excuses for these inconsistencies that don't hold water instead of just admitting that someone messed up.