- Introduce string primitive It would be just as the String class, except it would never be null, it would be empty string instead. How much boiler plate code does the null-checks cause for String. Autoboxing would work too.
- Make generics array-like By introducing generics Java creators worked hard to ensure backward compatibility. And, IMHO, failed. Consider:
As for consistency, other primitimes could also allow called methods of their relevant class alternatives.
- Array of Integer objects can be casted to array of Number objects, but not so collections.
- If you insert something illegal to such downcasted array, you get appropriate exception.
- Collections were not designed to throw exception due to incompatible type, as they were designed to always hold Object references. Changing that could break existing code.
- Any down/up-casting was not permitted on generic collections for the same reason.
- If you're not sure, what your legacy code inserts into raw collection, pass in the one, that hold Object and you'll get no issues.
- If the legacy code is supposed to only insert certain type (say String), so pass in appropriate collection. In case the legacy code inserts something else, you get exception at exact place where the bug in legacy code lays, rather than get an ugly ClassCastException miles away in the new code.
This type of for statement was introduced for readability, but having to check for null takes away half of that, because you have to wrap it in an if (you can avoid if by writing apropriate condition in traditional for).
IMO this enhanced for should treat null collection as empty.
package alias = com.company.product.whatever.pkg;
With this line alias.ClassName is identical to com.company.product.whatever.pkg.ClassName.
Another solution could be to use the unique part of package name: move backwards from class name to any dot until you get uniques name. Perhaps whatever.pkg.ClassName is enough to identify class and you don't need to type the full ugly package name.