Generic Method Type Safety

Tags: generics java
By : SCdF

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!

By : SCdF


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(...);
By : UlfJack

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{
	public UberThing createInstance() {
		return new UberThing();
By : jrudolph

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.

By : Hank Gay

This video can help you solving your question :)
By: admin