Skip to content
Advertisement

Java Method that returns different types of generic Lists

I’m currently trying to write a method that goes through a list of Ant-Objects and returns a list of AntScouts, that extend Ant. In general, List<Ant> can contain a lot of different Objects that inherit from Ant.

I also have an enum for the different kinds of ants:

JavaScript

This enum causes a warning:

JavaScript

And this is the method that currently returns a List<Ant>.

JavaScript

How can I write the method so that it get’s the AntType enum as argument and returns a List<AntScout> or List<AntWarrior> corresponding to the enum? I REALLY don’t want to use Class<T> clazz as argument since that would defeat the point of the enum. (I also use that enum elsewhere, so I can’t get rid of it)

How can I write the method so that it get’s the AntType enum as argument and returns a List or List corresponding to the enum?

Edit: This comment probably comes closest to the desired solution: Java Method that returns different types of generic Lists

Advertisement

Answer

Use the Power of Polymorphism

How can I write the method so that it get’s the AntType enum as argument and returns a List or List corresponding to the enum?

You’re overengineering your code for no good reason.

When you’re using inheritance, your classes should be designed in a way that allow to benefit from the Polymorphism.

I.e. by using super type Ant for all your objects and interacting with them through overridden behavior without a need to discriminate between the concrete implementations and operating via type casts.

Therefore, your method returning List<Ant> is quite fine.

And even if you wanted to obtain a List<AntQueen> or List<AntScout> as a result of the method execution then you would need a to use a generic type variable T, or rather T extends Ant, and that would imply that you need a mean of representing the T. And enum would not help you with this task because in Java enums can’t be generic. You need to provide as a method argument either an instance of T or a Class<T>.

JavaScript

But I would advise sticking with the initial version returning a List of super type Ant declaring method getType() which returns an instance of enum AntType.

JavaScript

And as I’ve said, Java-enums can’t be generic, there’s no way to obtain Class<T> through it. Hence, you can remove contrived method getClass() from AntType.

JavaScript

Simulated self-type

But if you’re still convinced that your application logic require the ability to generate a list of concrete type like List<AntScout> from a list of super type, then you can make use of a recursive type bound.

For that, you need to define the super type as Ant<T extends Ant<T>>.

This approach is also called a simulated self-type idiom and can be observed in the declaration of the parent type of all enums java.lang.Enum<E extends Enum<E>> and in some other parts of the JDK like method Collections.sort(List<T>) where T is defined as <T extends Comparable<? super T>>.

Let’s apply self-type idiom for this case.

Consider super type Ant defined as an interface, declaring a self-returning method (you can change into abstract class if you need to declare some skeletal implementations and common fields):

JavaScript

And here’s a couple of concrete classes:

JavaScript

That how we can perform conversion using self() method:

JavaScript

Usage example:

JavaScript

Output:

JavaScript

A link to Online Demo

Advertisement