This is an inherent problem with Java generics. Because generic types are erased at runtime, the jvm cannot decide which version of the getArrayOfTimespan()
method to call, as both will have the exact same signature: i.e. getArrayOfTimespan(List<Object> arg1)
. Hence your error. However if we look beyond the surface of Java generics an it's limitations, the Java compiler is actually telling you that you have a deeper problem.
It seems that both your Student
and Developer
classes share behaviour to some degree, as both have an identically named method that does the same thing: getStartDate()
. This would suggest that you could declare an interface that defines this common behaviour, e.g. "Startable" and then you will only need to define the getArrayOfTimespan()
method once for the interface.
interface Startable {
LocalDate getStartDate();
}
class Developer implements Startable { /* ... */ }
class Student implements Startable { /* ... */ }
class hierarchyValidator {
private LocalDate[][] getArrayOfTimespan(List<Startable> startables)
{
// ...
LocalDate startDate = startable.getStartDate();
// ...
}
}
Continuing on that track you will probably notice that you are doing some copy-pasting between your Developer
and Student
classes, as I am guessing that they not only share common behaviour, but also common structure (at least a private LocalDate startDate;
field). This is always an indicator that you should be extracting your common structure and behaviour into an abstract class. E.g:
abstract class Person {
private LocalDate startDate;
public LocalDate getStartDate() {
return this.startDate;
}
// ... etc ...
}
class Student extends Person{}
class Developer extends Person{}
class hierarchyValidator {
private LocalDate[][] getArrayOfTimespan(List<Person> people)
{
// ...
LocalDate startDate = person.getStartDate();
// ...
}
}
This will not only save you a lot of copy-pasting, but it will also make your code clearer to others, and help you to avoid bugs, when you change things in one place and forget about the copies.
So in short: If you realise that you are busy copy-pasting, or if you are having generics trouble, it almost always means you need inheritance. If your classes share common behaviour(i.e. have the same methods) --> use an interface. If your classes share common structure(i.e. have the same fields) --> use an abstract class.
Hope this helps, and good luck!