Search code examples
javaarraysstringcalendarbluej

Java 11+ "generic array creation" error (using BlueJ)


I'm new to Java and I'm using the current version of BlueJ to do my programming. When trying to initialize a string array containing all the days of the week I am greeted to the error message "generic array creation" I am curious on how to fix this as all the results I've found online have been quite old and out of date. The code is for a clock that can also track the day of the week. The code I have as follows:

daysOfWeek = new ArrayList<String>[]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};

I will be more than happy to update this post with any other information that may be needed to provide help. Thank you for your time.


Solution

  • As of Java 13, generic array creation is still forbidden. The reason has to do with the fact arrays know their component type at runtime but generics suffer from what's known as type-erasure. That said, your question has the following example:

    daysOfWeek = new ArrayList<String>[]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
    

    The above is trying to create an ArrayList<String>[]; in other words, an array of array-lists. This is most likely not what you actually want to do. Despite the name ArrayList, the class isn't directly involved in the creation of arrays—the name just means the list is backed by an array. Given that your data is simply the name of each day of the week, what you probably want is a String[] or List<String>:

    // array
    String[] daysOfWeek = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
    
    // list
    List<String> daysOfWeek = new ArrayList<>(List.of("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"));
    

    Note that if you're not using Java 11+ you can replace the use List#of with Arrays#asList(T...). If you are using Java 11+ then consider using the result of List#of directly, rather than copying the result into a modifiable ArrayList (assuming you don't plan on modifying the list).

    You may also want to consider using the java.time.DayOfWeek enum instead of a String to represent each day of the week. An enum is more type-safe, less prone to error, and allows easy interaction with any other java.time classes you may use.

    List<DayOfWeek> daysOfWeek = List.of(DayOfWeek.values());
    

    You should always default to using a List (or some other collection) before using an array. If you absolutely must use an array, you can work around the "generic array creation" error with the following:

    // unbounded T
    @SuppressWarnings("unchecked")
    T[] array = (T[]) new Object[size];
    
    // or if, for instance, T is upper-bounded by CharSequence
    @SuppressWarnings("unchecked")
    T[] array = (T[]) new CharSequence[size];
    
    // or if the component type is itself generic
    @SuppressWarnings("unchecked")
    Comparator<String>[] array = (Comparator<String>[]) new Comparator[size];
    

    However, all of the above is simply a compile-time trick. Each of the arrays will still allow any object that's an instance of the raw component type to be stored without throwing an ArrayStoreException at runtime. In other words, the first array will still accept any Object, the second array will still accept any CharSequence, and the third array will still accept any Comparator<?>. This is why an "unchecked cast" warning is emitted for each of the above; that is, if there were no @SuppressWarnings("unchecked") annotation present.