I know - but I'm not familiar with the situation where I'd have to to that in java. Do you mean e.g.
Foo(object x)
{
if (X is List<int>)
...
else
...
}I know - but I'm not familiar with the situation where I'd have to to that in java. Do you mean e.g.
Foo(object x)
{
if (X is List<int>)
...
else
...
} public Object[] toArray()
public <T> T[] toArray(T[])
You cannot turn an ArrayList<T> into a T[], for example, without passing a T[] into the function so that you can grab the type from the passed parameter at runtime. C#, which retains the generic information at runtime doesn't need this so you can just do public T[] toArray()
The other place I've seen this come up is with Exceptions- you cannot catch a generic Exception. It's pretty annoying now that Java 8 has streams because you cannot have a checked exception abort out of processing a Stream unless you either 1) catch Exception (rather than the specific subclass) and deal with everything or 2) catch the checked exception in the lambda, wrap it in a runtime exception, rethrow it, and then catch the wrapped exception. void AddAnItem<T>(List<T> aList) where T : new()
{
aList.Add(new T());
}
Or for instantiating generic types: public TColl CreateACollectionAndAddAnItem<TColl, T>(T item)
where TColl : ICollection<T>, new()
{
TColl aList = new TColl();
aList.Add(item);
return aList;
}
// Usage
List<string> myList = CreateACollectionAndAddAnItem<List<string>, string>("hello"); <T> static void addItem(List<T> list, Class<T> type) {
T item = type.newInstance();
list.add(item);
}There are some ways to introspect generic types in Java, but you need a concrete binding. For instance, if a method returns List<Integer>, you can in fact see that it returns List<Integer> and not just List. Method.getGenericReturnType() would return a ParameterizedType with a List raw type and Integer type arguments. But that requirement for it to be a concrete binding means it's not really helpful from the context of writing a generic class or method in the first place.
Using the above example, I'm not sure how you could desugar that without having the type known to the runtime. The generic method is going to be the same code no matter the type provided, but the type provided is necessary in order to know the type to construct. So either the runtime must provide the type, or it must be given as a parameter.
Additionally, glossing over the issue like that creates a huge trade-off. Now programmers must build a mental model of when the compiler can and can't do the type binding. The difficulty of building such a mental model accurately is one of the central complaints against Rust's borrow and lifetime checker(s).