array cast Java 8 vs Java 9

后端 未结 2 644
遥遥无期
遥遥无期 2021-01-02 06:51

Does anyone have insights on why this code works on java 8 but not on java 9

String[] strings = (String[]) Arrays.asList(\"foo\", \"bar\").toArray();
for (St         


        
相关标签:
2条回答
  • 2021-01-02 07:20

    Seems like it might be due to the change (coll) Arrays.asList(x).toArray().getClass() should be Object[].class

    Looks like they fixed a bug that toArray could return types other than Object.

    Quoting the release notes

    This may cause code that was expecting the old behavior to fail with a ClassCastException...If this problem occurs, rewrite the code to use the one-arg form toArray(T[]), and provide an instance of the desired array type. This will also eliminate the need for a cast.

    So it seems like you'll need to file a bug in the Hive repo to update the code to work after this change.

    Looks like they actually added a configuration value in a future commit which if set with a certain value would actually avoid the code path causing the issue. https://github.com/apache/hive/commit/07492e0d2f1942c1794a3190610e10207c850cf7#diff-ca39aa4869cc58909a31c761cd7a27ccR257

    Maybe you can upgrade to a version that has this and use this configuration to avoid the problem. So long as you don't care about the functionality that requires that code path. Seems like the code causing the problem is selecting which URI to use randomly instead of just picking the first one out of a list.

    0 讨论(0)
  • 2021-01-02 07:28

    The implementation of Arrays.ArrayList.toArray seems to have been changed. The old implementation was to just clone the backing array:

    private final E[] a;
    
    ArrayList(E[] array) {
        a = Objects.requireNonNull(array);
    }
    
    @Override
    public Object[] toArray() {
        return a.clone();
    }
    

    The new implementation forces the returned array to be an Object[]:

    @Override
    public Object[] toArray() {
        return Arrays.copyOf(a, a.length, Object[].class);
    }
    

    To be clear, though, in Java 8 the cast only worked because the backing array was originally a String[], created by the asList varargs. Implicitly all that was happening was new String[] {"foo", "bar"}.clone(), but the array was passed through the asList List implementation.


    As for fixing the broken dependency, I don't think there's a way besides either using a Java 8 run-time environment or rewriting what was introduced in that commit. Filing a bug report seems like the right thing to do.

    0 讨论(0)
提交回复
热议问题