Reputation: 31
I'm attempting to create a method that will add elements from a defined list, into a generic list.
Here is the code:
private List<IEntity> entities = new ArrayList<IEntity>();
public <T extends IEntity> List<T> values(Class<T> type) {
List<T> types = new ArrayList<T>();
for (IEntity v : entities) {
types.add(v); //Error
}
return types;
}
The sytax error occurs on types.add(v);
with the error message (T) in List cannot be applied to (com.test.entities.IEntity)
.
Is there any way to do what I'm trying to do efficiently without having to cast?
Upvotes: 1
Views: 274
Reputation: 95376
The compiler is giving you a type error because your program is not safe.
You have a List<T>
. You don't know what T
is, just that it extends IEntity
. (Let's use Number as an example instead of IEntity
, to make it more clear.) So you have a List of some kind of Number, maybe it's a List<Integer>
, or maybe a List<Float>
, you don't know. And you're trying to add a Number to it. But you have no reason to believe that this list can hold Number! A List<Integer>
cannot hold an arbitrary Number, because you can't put Long or Float or Short into a List<Integer>
-- Java generics are invariant.
So, basically your program is broken and the compiler is telling you so.
Upvotes: 9
Reputation: 151
If you want to make a generic class you could do something like this.
private class MyClass<T extends IEntity> {
private List<T> entities;
...
public List<T> values() {
List<T> types = new ArrayList<>();
for (T v : entities) {
types.add(v); // All Good
}
return types;
}
}
interface IEntity { ... }
interface ISubEntity extends {...}
Then when you know you are using ISubEntity, you can instantiate as follows;
MyClass<ISubEntity> myClass = new MyClass<>();
Subsequent calls to values would then return a List typed for you.
Here is the formal doc online about generics.
Upvotes: 0
Reputation: 1095
Because you don't provide more information about the concrete structure of what you're going to do, it's difficult to offer a better solution.
interface Entity {} // In Java, unlike in .NET environment, interface names do not begin with "I". You write Entity or EntityInterface, sometimes also EntityInt
class EntityImpl {
private final List<Entity> entities = new ArrayList<>();
// List of T is undefined
public <T extends Entity> List<T> getValues(Class<T> type) { // in Java it's important to write "get" for a getter-method before the property-name, if it's not a boolean-getter.
List<T> types = new ArrayList<>();
types.addAll((Collection<? extends T>) entities);
return types;
}
}
Upvotes: 0
Reputation: 632
You can't insert a IEntity
to a list that holds subclasses of IEntity
- T extends IEntity
. You would need a list that holds super classes of IEntity
to put an IEntity
in it - T super IEntity
.
Upvotes: 0