A very specific problem with Java generics is how to return the same type that was passed to the method?

In my game engine, I have a list of Entity objects, of which there are many subclasses (e.g. Player , Cube , Camera , etc.). I would like to have a method in which I pass the Class object, and in the end we get a list of the same class - for example. I would like to say something like this:

 List<Box> boxes = getEntities(Box.class); 

So far I have this:

 public List<Entity> getEntities(Class<? extends Entity> t) { ArrayList<Entity> list = new ArrayList<>(); for (Entity e : entities) { if (e.getClass() == t) { list.add(e); } } return Collections.unmodifiableList(list); } 

But, of course, returns List of Entity s, which means that every instance in the List must be added to the Box class. Is there a way to do it right in Java?

+4
source share
3 answers

I recommend the following, which builds on existing answers, but avoids @SuppressWarnings , etc:

 public <E extends Entity> List<E> getEntities(Class<E> type) { List<E> list = new ArrayList<>(); for (Entity e : entities) { if (type.isInstance(e)) { list.add(type.cast(e)); } } return Collections.unmodifiableList(list); } 

Or if you use Guava :

 public <E extends Entity> ImmutableList<E> getEntities(Class<E> type) { return ImmutableList.copyOf(Iterables.filter(entities, type)); } 
+3
source

Make your method common with the upper bound.

 public <T extends Entity> List<T> getEntities(Class<T> t) { 

Then replace Entity with T in the next line of your code.

 ArrayList<T> list = new ArrayList<>; 

EDIT

As @arshajii pointed out in a comment, e will need to be distinguished from T to match the list type.

+1
source

Try the following:

 public static List<? extends Entity> getEntities(Class<? extends Entity> t) { ArrayList<Entity> list = new ArrayList<Entity>(); for (Entity e : entities) { if (e.getClass() == t) { list.add(e); } } return Collections.unmodifiableList(list); } 

and then you can call:

 List<Box> boxes = (List<Box>) getEntities(Box.class); 

Now you do not need to drop every object of the list.

-2
source

Source: https://habr.com/ru/post/1491527/


All Articles