Search code examples
assertj

How to override generic isEqualTo from AbstractAssert


The method with a generic parameter in its interface:

interface Assert<S, A> {
    S isEqualTo(A expected);

is overridden with Object parameter in its abstract class:

abstract class AbstractAssert<S ..., A> implements Assert<S, A> {
    @Override
    S isEqualTo(Object expected)

How to override isEqualTo() with the generic parameter A of Assert<S, A>, as

class MyAssert extends AbstractAssert<MyAssert, MyClass> {
    @Override
    MyAssert isEqualTo(MyClass expected)

fails because of type erasure:

name clash: isEqualTo(MyClass) in MyAssert overrides a method whose erasure is the same as another method, yet neither overrides the other

first method: isEqualTo(Object) in AbstractAssert
second method: isEqualTo(A#2) in Assert
where A#1,A#2 are type-variables:
A#1 extends Object declared in class AbstractAssert
A#2 extends Object declared in interface Assert

Is there another way?

What assertJ gain of shadowing the generic parameter with Object?


Solution

  • The reason for isEqualTo to take an Object as parameter is to be flexible.

    Example:

    Object name = "John";
    // would not compile if isEqualTo expected a String parameter 
    assertThat("John").isEqualTo(name);
    

    You can't override a method and narrow its parameters type.