Is there a case where using type witness is absolutely needed?
Prior to Java 8 yes. There would be the error for calling snippet code:
void processStringList(List<String> stringList) {
// process stringList
}
And then if you call this method with collection.emptyList() compiler could not infer the type.
processStringList(Collections.emptyList());
The error would be List<Object> cannot be converted to List<String>
So you had to write it this way:
processStringList(Collections.<String>emptyList());
In JDK 8 and after compiler can infer it base On the method definition that the type in String. Then this will work:
processStringList(Collections.emptyList());
For more information check the Type Inference