Skip to content

Commit 2c3ab68

Browse files
committed
Remove SizableArrayList reflection hack
I doubt that addAll with a collection of nulls can approach the performance of just hacking the size value -- it's hard to beat O(1), and in Java newly allocated object arrays are already filled with nulls, so needing to addAll these nulls on top is frustratingly wasteful. But Java 17+ tightens the screws on reflection, making the reflection-based approach too fraught to use anymore. C'est la vie.
1 parent dee35f1 commit 2c3ab68

File tree

1 file changed

+2
-36
lines changed

1 file changed

+2
-36
lines changed

src/main/java/org/scijava/util/SizableArrayList.java

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@
2929

3030
package org.scijava.util;
3131

32-
import java.lang.reflect.Field;
3332
import java.util.ArrayList;
3433
import java.util.Collection;
34+
import java.util.Collections;
3535

3636
/**
3737
* An {@link ArrayList} whose size can be adjusted more efficiently.
@@ -84,42 +84,8 @@ public void setSize(final int size) {
8484
else {
8585
// need to add some elements
8686
ensureCapacity(size);
87-
final boolean hackSuccessful = hackSize(size);
88-
if (!hackSuccessful) {
89-
// explicitly increase the size by adding nulls
90-
while (size() < size) add(null);
91-
}
87+
addAll(Collections.nCopies(size - oldSize, null));
9288
}
9389
}
9490

95-
// -- Helper methods --
96-
97-
private boolean hackSize(final int size) {
98-
// HACK: Override the size field directly.
99-
final int oldSize;
100-
try {
101-
final Field sizeField = ArrayList.class.getDeclaredField("size");
102-
sizeField.setAccessible(true);
103-
oldSize = (Integer) sizeField.get(this);
104-
sizeField.set(this, size);
105-
106-
// NB: Check that it worked. In the case of Java 1.7.0_45, it is possible
107-
// for the capacity to not *actually* be ensured, in which case
108-
// subsequently attempting to get the (size - 1)th value results in
109-
// ArrayIndexOutOfBoundsException. So let's be safe and verify it here.
110-
try {
111-
get(size - 1);
112-
}
113-
catch (final Exception exc) {
114-
// NB: Restore the previous size, then fail.
115-
sizeField.set(this, oldSize);
116-
return false;
117-
}
118-
}
119-
catch (final Exception exc) {
120-
return false;
121-
}
122-
return true;
123-
}
124-
12591
}

0 commit comments

Comments
 (0)