Question

I have the concept of NodeTypes and Nodes. A NodeType is a bunch of meta-data which you can create Node instances from (a lot like the whole Class / Object relationship).

I have various NodeType implementations and various Node implementations.

In my AbstractNodeType (top level for NodeTypes) I have ab abstract createInstance() method that will, once implemented by the subclass, creates the correct Node instance:

public abstract class AbstractNodeType {
  // ..

  public abstract <T extends AbstractNode> T createInstance();
}

In my NodeType implementations I implement the method like this:

public class ThingType {
  // ..

  public Thing createInstance() {
    return new Thing(/* .. */);
  }
}

// FYI
public class Thing extends AbstractNode { /* .. */ }

This is all well and good, but public Thing createInstance() creates a warning about type safety. Specifically:

Type safety: The return type Thing for createInstance() from the type ThingType needs unchecked conversion to conform to T from the type AbstractNodeType

What am I doing wrong to cause such a warning?

How can I re-factor my code to fix this?

@SuppressWarnings("unchecked") is not good, I wish to fix this by coding it correctly, not ignoring the problem!

Was it helpful?

Solution

You can just replace <T extends AbstractNode> T with AbstractNode thanks to the magic of covariant returns. Java 5 added support, but it didn't receive the pub it deserved.

OTHER TIPS

Two ways:

(a) Don't use generics. It's probably not necessary in this case. (Although that depends on the code you havn't shown.)

(b) Generify AbstractNodeType as follows:

public abstract class AbstractNodeType<T extends AbstractNode> {
  public abstract T createInstance();
}
public class ThingType<Thing> {
  public Thing createInstance() {
    return new Thing(...);
  }
}

Something like that should work:

interface Node{
}
interface NodeType<T extends Node>{
    T createInstance();
}
class Thing implements Node{}
class ThingType implements NodeType<Thing>{
    public Thing createInstance() {
        return new Thing();
    }
}
class UberThing extends Thing{}
class UberThingType extends ThingType{
    @Override
    public UberThing createInstance() {
        return new UberThing();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top