Reputation: 1461
First of all, I have not much experience with java generics.
I hava a method kind of that:
public static Set<Object> getObjects(Class<? extends Object> clazz) {
if (clazz == null) {
clazz = Object.class;
}
Set<Object> result = new HashSet<Object>();
Object object;
for (/*a loop*/) {
object = /*get an object*/;
if (clazz.isInstance(object)) {
result.add(object);
}
}
return result;
}
And I thought it would be better to use generics, to get the right return type. So I changed the method to this:
public static <T> Set<T> getObjects(Class<T> clazz) {
if (clazz == null) {
//what should I do instead? Throw exception?
}
Set<T> result = new HashSet<T>();
Object object;
for (/*a loop*/) {
object = /*get an object*/;
if (clazz.isInstance(object)) {//or should I use object instanceof T? If yes, I don't event use clazz. Would it be bad practice?
result.add((T) object);
}
}
return result;
}
My questions: See comments in second code. Should I use generics here? Do I use it right? How would you do it?
Upvotes: 0
Views: 100
Reputation: 6392
First, yes, you should probably throw an IllegalArgumentException or NullPointerException if null is passed as the method argument.
Also, this line
result.add((T) object);
should probably use clazz to do the cast. Because the T is erased you don't get any safety from the casting and BadThings(tm) can happen. So, it should really look like
result.add(clazz.cast(object));
Also, if you're using Java8 then you might like to consider using the streams API. Assuming there's some method you can call which returns a collection of 'all' the objects, then your method would look like
public static <T> Set<T> getObjects(Class<T> clazz) {
if (clazz == null) {
throw new IllegalArgumentException();
}
return getAllTheObjects().stream()
.filter(clazz::isInstance)
.map(clazz::cast)
.collect(Collectors.toSet());
}
Upvotes: 4