5

I have below code which fails with IllegalArgumentException

public EnumSet<test> getData(){  // Line 1
   return EnumSet.copyOf(get(test))) // Line 2
}



private Collection<Test> get(Test[] test){  //Line 1
 test= test==null ? new Test[0] : test;     // line 2
 return Array.asList(test) //Line 3
}

if test is null , then line 2 of get function creates empty array of Test and EnumSet.copyOf(get(test)) throws IllegalArgumentException

I dont understand why this exception is thrown ?

  • 4
    The javadoc says: *the specified collection must contain at least one element (in order to determine the new enum set's element type)*. – JB Nizet Apr 30 '19 at 16:04
  • 2
    See documenation: https://docs.oracle.com/javase/7/docs/api/java/util/EnumSet.html#copyOf(java.util.Collection) – gudok Apr 30 '19 at 16:05
  • See also: https://stackoverflow.com/questions/32722808/java-enumset-copyof-is-there-a-room-for-improvement/55925249#55925249 – Thomas Bitonti Apr 30 '19 at 16:32

1 Answers1

7

An EnumSet uses some reflection to identify the type of its elements. (The set uses the "ordinal" of the enum values to track whether each element is included or not.)

When you create an EnumSet with copyOf(Collection), it checks to see if the collection is an EnumSet. If it is, it uses the same type as the source set. Otherwise, it attempts to call getClass() on the first element in the source collection. If the collection is empty, there is no first element, and nothing to query for its class. So it fails in that case ("throws IllegalArgumentException if c is not an EnumSet instance and contains no elements").

To create an empty EnumSet, you need to determine the class yourself, and use noneOf().

Collection<Test> tests = get(test);
return tests.isEmpty() ? EnumSet.noneOf(Test.class) : EnumSet.copyOf(tests);
erickson
  • 265,237
  • 58
  • 395
  • 493
  • 1
    Or omit the detour of converting the array to a `Collection` before creating the `EnumSet`, i.e. just use `EnumSet result = EnumSet.noneOf(Test.class); if(test!=null) Collections.addAll(result, test); return result;` – Holger Apr 30 '19 at 17:05