elharo commented on code in PR #589:
URL: https://github.com/apache/maven-war-plugin/pull/589#discussion_r2557417941
##########
src/main/java/org/apache/maven/plugins/war/Overlay.java:
##########
@@ -325,14 +325,12 @@ public int hashCode() {
private String[] parse(String s) {
final List<String> result = new ArrayList<>();
- if (s == null) {
- return result.toArray(new String[result.size()]);
- } else {
+ if (s != null) {
String[] tokens = s.split(",");
for (String token : tokens) {
result.add(token.trim());
}
- return result.toArray(new String[result.size()]);
}
+ return result.toArray(new String[0]);
Review Comment:
That's no longer needed or recommended and hasn't been for a while according
to copilot. Gemini concurs:
The practice of passing a zero-sized array to the Java Collections
`toArray(T[] a)` method, rather than an array of the collection's expected
size, is the **current recommended best practice**.
This recommendation is based on optimizing performance and simplifying code
under the hood, reversing an older, less efficient practice.
---
## 1. The Older (Less Recommended) Practice
The older, less efficient practice was to pre-allocate an array based on the
collection's current size:
$$\text{List<String>} \space \text{list} = \dots;$$
$$\text{String[]}\space \text{array} =
\text{list}.\text{toArray}(\text{new}\space
\text{String}[\text{list}.\text{size}()]);$$
### Rationale for the Old Way (Pre-JDK 6)
The original idea was to avoid a costly internal allocation in the
`toArray()` method. Developers pre-allocated the array to be large enough,
ensuring the method simply populated and returned the provided array, thereby
bypassing a potentially slower internal array creation step using reflection in
older Java versions.
---
## 2. The Current Recommended Practice (Zero-Sized Array)
The modern, recommended best practice is to pass a zero-sized array of the
correct type:
$$\text{List<String>} \space \text{list} = \dots;$$
$$\text{String[]}\space \text{array} =
\text{list}.\text{toArray}(\text{new}\space \text{String}[0]);$$
### Why This is Now Better (The Performance Shift in Modern Java)
Since **JDK 6 and later**, the implementation of `toArray(T[] a)` has been
highly optimized, making the zero-sized array approach superior for the
following reasons:
#### A. Optimization of Internal Array Allocation
When you pass a zero-sized array (`new T[0]`):
* The `toArray` method knows immediately that it must allocate a new array.
* This internal allocation is now highly optimized by the JVM runtime,
making it faster and more efficient than the reflection-based allocation in
legacy JVMs.
#### B. Avoiding Unnecessary Allocations
Using `new T[0]` is more memory-efficient when the list is empty:
* If the list is **empty**, the method simply returns an **optimized,
pre-allocated, zero-length array** instance without creating a new object.
* If the list is **not empty**, the method performs a single, optimized
allocation of the correct size.
When you pass `new T[list.size()]`, you are always incurring the cost of
that array allocation, even if the list size is zero, which is slightly less
efficient.
#### C. Code Readability and Simplicity
The zero-sized approach is cleaner and less verbose. It expresses the
developer's intent clearly: "I need an array of this type; I trust the library
to handle the optimal size."
***
**In summary:** The previous performance concern regarding the overhead of
internal array creation is no longer valid in modern JVMs. Passing a zero-sized
array simplifies your code and avoids unnecessary allocation when the source
collection is empty.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]