Return type of overridden method in Java

In the below Haxe code, I’ve got a function in B, add, that overrides a function in A. The return type of A.add is A, and the return type of B.add is B; note the necessary cast of the response in B.add to get the expected type. In the main function, when I call the B.add function I get an object of type B, and the method signature seems to be outputting a B. However, when I compile this to Java, the return type of the B.add function is A. I tried this with Haxe 4.1.4 - is there something I’m missing here? I would have expected since I’m explicitly returning B that the return type would be B, not A. I’m trying to use this code in some call chains, and it’s creating a bunch of extra unnecessary casts.

Haxe Code:

class A{
    public function new(){}
    public function add(c:C):A {
        // do something with c
        return this;
    }
}

class B extends A{
    public function new(){
        super();
    }

    public override function add(c:C):B {
        return cast(super.add(c), B);
    }
}

class C{
    public function new(){}
}

class CastTest{
    public static function main(){
        var v:B = new B().add(new C());
        trace(Type.getClassName(Type.getClass(v)));
        $type(new B().add); // prints (c : C) -> B
    }
}

B.add function, after compiling with haxe.exe --java CastTest CastTest.hx

@Override public haxe.root.A add(haxe.root.C c)
{
    //line 15 "D:\\tmp\\hx_cast\\CastTest.hx"
    return ((haxe.root.B) (super.add(c)) );
}

IIRC this doesn’t work correctly otherwise because the method isn’t recognized as an override if the return type is different.

Would that be considered a bug then and worth submitting an issue for? It seems like all the right information is there to output the requested return type, and java (at least, haven’t checked other languages) certainly supports returning a subclass of the overridden method’s class.

I’m not sure how this works through javac, but at JVM-level methods are only considered equal (and thus overridden) if their signature matches. This wouldn’t be the case if the return type differs.

Gotcha. javac does indeed handle it fine, but I can see that making sense at lower levels. Thanks!

The Java spec does allow different return types for overridden methods as long as the overridden return type is a subtype of the original. See here for the documentation.