0

I have a question about generics.

I defined base classes ServiceObject and ServiceObjectsList

class ServiceObject {};
class ServiceObjectsList<T extends ServiceObject> extends ArrayList<T> {};

Then I defined some descendant classes:

class UserServiceObject extends ServiceObject {};
class UserServiceObjectsList extends ServiceObjectsList<UserServiceObject> {};

class ItemServiceObject extends ServiceObject {};
class ItemServiceObjectsList extends ServiceObjectsList<ItemServiceObject> {};

// etc...

Now I need to treat UserServiceObjectsList as ServiceObjectsList<ServiceObject>:

If I write:

ServiceObjectsList displayableServiceObjects; 

then I can't iterate over them:

for (ServiceObject serviceObject : displayableServiceObjects)

throw error "Incompatible types".

If I write ServiceObjectsList<ServiceObject> displayableServiceObjects then I can't assign UserServiceObjects:

displayableServiceObjects = new UserServiceObjects();

It throws the very same "Incompatible types" error;

What I do wrong?

All ServiceObjects, ServiceObjectsLists and they descendants realy needed. Then encapsulate some functional.

atomAltera
  • 1,702
  • 2
  • 19
  • 38

3 Answers3

2

You should specify the generic type in the declaration:

ServiceObjectsList<? extends ServiceObject> displayableServiceObjects; 

and the "Incompatible types" error will be gone...

jamp
  • 2,159
  • 1
  • 17
  • 28
1

You cannot treat your list as ServiceObjectsList<ServiceObject>, because that is not what it is. Casting is not allowed.

You CAN however cast you list as ServiceObjectsList<? extends ServiceObject> - a list of something that extends ServiceObject.

slartidan
  • 20,403
  • 15
  • 83
  • 131
1

The short answer is what I think you're trying to achieve do can't be done, because ArrayList and ArrayList aren't really separate classes like they are in C++, where templates are more like clever macros than Java generics.

When you define class ServiceObjectsList<T extends ServiceObject> extends ArrayList<T> {} you have created a proper subclass of ArrayList, but ServiceObjectsList is still generic. Then when you declare a variable ServiceObjectsList displayableServiceObjects; without adding a type parameter, it's the same as ServiceObjectsList<Object>. The qualifier <T extends ServiceObject> will be checked at compile-time, but only if you declare a type-parameter on your variable.

Sophistifunk
  • 4,742
  • 4
  • 28
  • 37