Search code examples
javagenericsinterfaceself-reference

How can I refer to the class type a interface is implementing in Java?


I came to a problem with interfaces in a program I'm making. I want to create a interface which have one of its methods receiving/returning a reference to the type of the own object. It was something like:

public interface I {
    ? getSelf();
}

public class A implements I {
    A getSelf() {
        return this;
    }
}

public class B implements I {
    B getSelf() {
        return this;
    }
}

I can't use an "I" where it's a "?", because I don't want to return a reference to the interface, but the class. I searched and found that there are no way to "self-refer" in Java, so I can't just substitute that "?" in the example for a "self" keyword or something like this. Actually, I came up to a solution that goes like

public interface I<SELF> {
    SELF getSelf();
}

public class A implements I<A> {
    A getSelf() {
        return this;
    }
}

public class B implements I<B> {
    B getSelf() {
        return this;
    }
}

But it really seems like a workaround or something alike. Is there another way to do so?


Solution

  • There is a way to enforce using ones own class as a parameter when extending an interface:

    interface I<SELF extends I<SELF>> {
        SELF getSelf();
    }
    
    class A implements I<A> {
        A getSelf() {
            return this;
        }
    }
    
    class B implements I<A> { // illegal: Bound mismatch
        A getSelf() {
            return this;
        }
    }
    

    This even works when writing generic classes. Only drawback: one has to cast this to SELF.

    As Andrey Makarov noted in a comment below this does not work reliably when writing generic classes.

    class A<SELF extends A<SELF>> {
        SELF getSelf() {
            return (SELF)this;
        }
    }
    class C extends A<B> {} // Does not fail.
    
    // C myC = new C();
    // B myB = myC.getSelf(); // <-- ClassCastException