3

I want to define the following Java class:

public class DummyTemplate<S, D extends DummyTemplate<S,D>> {

S value;
D next;
public DummyTemplate(S value, D next) {
    super();
    this.value = value;
    this.next = next;
}


public static DummyTemplate<String, DummyTemplate>  factory(){

    return  new DummyTemplate<String, DummyTemplate>("wohoo", null);
}

}

created so i can subclass:

public class DummyTemplateSubclass<S,  D extends DummyTemplateSubclass<S,D>> extends DummyTemplate<S, D>

(and the factoty of subclass returns DummyTemplateSubclass).

But the definition creates compile error:

Bound mismatch: The type DummyTemplate is not a valid substitute for the bounded parameter <D extends DummyTemplate<S,D>> of the type DummyTemplate<S,D>

Probably because the DummyTemplate must have parameters, how to define it then? i get the error

it compiles howewer only :

public static<D extends DummyTemplate<String,D>> D  factory()

but then i got trouble on subclass:

public static<D extends DummyTemplateSubclass<String,D>> D  factory(){

Name clash: The method factory() of type DummyTemplateSubclass has the same erasure as factory() of type DummyTemplate but does not hide it

2 Answers 2

2

When you make a self-referencing template parameter like that, you can't use the template directly, because it's ever-expanding:

DummyTemplate<String, DummyTemplate<String, DummyTemplate<String, ...>>>

To use it, you must create a subclass:

public class DummyTemplate<S, D extends DummyTemplate<S,D>> {
    S value;
    D next;
    public DummyTemplate(S value, D next) {
        this.value = value;
        this.next = next;
    }
}

public class StringTemplate extends DummyTemplate<String, StringTemplate> {
    public StringTemplate(String value, StringTemplate next) {
        super(value, next);
    }
    public static StringTemplate factory() {
        return new StringTemplate("wohoo", null);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

Because the factory method is static and the second parameter of DummyTemplate is D extends DummyTemplate<S, D>, you need to declare a new generic type, as follows:

public static <T extends DummyTemplate<String, T>> DummyTemplate<String, T> factory() {
    return new DummyTemplate<String, T>("wohoo", null);
}

Then the subclass compiles just fine:

public class DummyTemplateSubclass<S, D extends DummyTemplateSubclass<S, D>> extends DummyTemplate<S, D> {
    public DummyTemplateSubclass(S value, D next) {
        super(value, next);
    }

    public static <T extends DummyTemplateSubclass<String, T>> DummyTemplateSubclass<String, T> factorySubclass() {
        return new DummyTemplateSubclass<String, T>("wohoo", null);
    }
}

If you want to remove the static keyword from factory, then the code simplifies:

public class DummyTemplate<S, D extends DummyTemplate<S, D>> {
    S value;
    D next;

    public DummyTemplate(S value, D next) {
        this.value = value;
        this.next = next;
    }

    public DummyTemplate<String, D> factory() {
        return new DummyTemplate<String, D>("wohoo", null);
    }
}

public class DummyTemplateSubclass<S, D extends DummyTemplateSubclass<S, D>> extends DummyTemplate<S, D> {
    public DummyTemplateSubclass(S value, D next) {
        super(value, next);
    }

    @Override
    public DummyTemplateSubclass<String, D> factory() {
        return new DummyTemplateSubclass<String, D>("wohoo", null);
    }
}

6 Comments

public static DummyTemplate<String, D> factory() does not compile, also does not public static<D> DummyTemplate<String, D> factory()
@user184868 My apologies, I accidentally removed static from it earlier without noticing. You should now be free to create a factory method for your subclass, but remember that static methods cannot be overridden in Java.
nah i still got Name clash: The method factory() of type DummyTemplateSubclass<S,D> has the same erasure as factory() of type DummyTemplate<S,D> but does not hide it
Yeah, you can't use the same name factory in the subclass, as static methods cannot be overridden. I've named the method factorySubclass in DummyTemplateSubclass.
hmm, ok. <br> now i tryed to use it not static like:<br> public DummyTemplate<String, D> factory(){ <br> return new DummyTemplate<String, D>("DummyTemplate", null);<br> } then i subclass:<br> public class DummyTemplateSubclass<S, D extends <br>DummyTemplateSubclass<S,D>> extends DummyTemplate<S, D>{ and then<br> DummyTemplateSubclass<String,?> dummy = new <br>DummyTemplateSubclass<>("noob", null);<br> DummyTemplate<String, ?> fa = dummy.factory();<br> System.out.println(fa.getClass()); returns class templates.DummyTemplate, but D must be DummyTemplateSubclass
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.