Skip to content

Fix ArrayStoreException in ObjectArrays.concat(element, array) / concat(array, element) - #8677

Open
Junnie18 wants to merge 1 commit into
google:masterfrom
Junnie18:fix-objectarrays-concat-arraystoreexception
Open

Junnie18 wants to merge 1 commit into
google:masterfrom
Junnie18:fix-objectarrays-concat-arraystoreexception

Conversation

@Junnie18

Copy link
Copy Markdown

Summary

ObjectArrays.concat(T element, T[] array) and ObjectArrays.concat(T[] array, T element) build their result array with the same runtime component type as the input array (via newArray/Arrays.copyOf), then store element directly into it. If element's runtime type isn't assignable to that component type — which erasure allows the caller to do, since both methods are generic — storing it throws ArrayStoreException instead of succeeding:

String[] array = new String[0];
Object[] concatenated = ObjectArrays.<Object>concat(array, 0); // throws ArrayStoreException

This is inconsistent with ObjectArrays.concat(T[], T[], Class<T>), which never has this problem because it always builds its result array from the explicitly supplied Class<T> rather than inferring a component type from one of its array arguments.

Fix

Each of the two single-element overloads now checks whether element is storable in an array with the same component type as the input array before allocating the result that way. If it isn't, it falls back to a plain Object[] (unchecked-cast back to T[]), which mirrors the existing unsoundlyCovariantArray pattern already used elsewhere in this file for the same class of unsoundness. In the overwhelmingly common case (element and array are actually type-compatible), behavior and the returned array's runtime type are unchanged.

No public API was changed.

Testing

Added 4 regression tests to ObjectArraysTest (prepend/append, with both an empty and a non-empty backing array) that concatenate a String[] with an Integer via an explicit <Object> type witness, reproducing the exact shape of bug report's repro. Verified:

  • Before the fix: all 4 new tests fail with ArrayStoreException, confirming they exercise the reported bug.
  • After the fix: mvn test -pl guava,guava-tests -am -Dtest=ObjectArraysTest → 30/30 pass.
  • Ran the full com.google.common.collect.*Test suite (207 test classes) afterward to check for regressions: all pass.
  • Formatted the changed source file with google-java-format.

Fixes #3768.

…at(T[], element).

Both single-element concat overloads built the result array with the same
runtime component type as the input array (via newArray/Arrays.copyOf),
then stored the new element into it directly. When the element's runtime
type wasn't assignable to that component type (e.g. concatenating a
String[] with an Integer, both erased to Object at the call site), storing
the element threw ArrayStoreException instead of succeeding, unlike
concat(T[], T[], Class<T>), which never has this problem since it builds
its result array from an explicit Class.

Now each method checks whether the element is storable in an array of the
same type as the input before allocating; if not, it falls back to a plain
Object[] (unchecked-cast back to T[], mirroring the existing
unsoundlyCovariantArray pattern used elsewhere in this file), so no
exception is thrown.

Fixes google#3768
@google-cla

google-cla Bot commented Sep 17, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@ionik0

ionik0 commented Sep 17, 2026

Copy link
Copy Markdown

Hey @Junnie18 ... go to https://cla.developers.google.com/ and sign in , or the googleBot will block it, individual CLA is a few minutes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ObjectArrays.concat(T[], T) and (T, T[]) can throw ArrayStoreException

2 participants