Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid "Type mismatch" in static generic factory method?

Either I'm too stupid to use google, or nobody else encountered this problem so far.

I'm trying to compile the following code:

public interface MyClass {
  public class Util {
    private static MyClass _this;
    public static <T extends MyClass> T getInstance(Class<T> clazz) {
      if(_this == null) {
        try {
          _this = clazz.newInstance();
        } catch(Exception e) {
          e.printStackTrace();
        }
      }
      return _this;
    }
  }
}

Howerer, in the line "return _this;" I get the error "Type mismatch: cannot convert from MyClass to T" Why is this? T extends MyClass, so where is the problem? If I change the line to "return (T)_this;", i just get a warning about the unchecked cast, but I don't like warnings ;-) Is there a way to achieve what i want without an error or warning?

like image 653
MarioP Avatar asked May 31 '11 20:05

MarioP


1 Answers

Imagine you have two implementations of MyClass, Foo and Bar. As a field of type MyClass, _this could be a Foo or a Bar.

Now, since your getInstance method returns <T extends MyClass>, it's legal to call it any of these ways:

MyClass myClass = Util.getInstance(MyClass.class);

This doesn't work if it's the first call, because MyClass is an interface and can't be instantiated with newInstance().

Foo foo = Util.getInstance(Foo.class);
Bar bar = Util.getInstance(Bar.class);

Now, what would happen if _this was an instance of Foo and you called Util.getInstance(Bar.class)? That's why you aren't allowed to do this.

like image 187
ColinD Avatar answered Sep 18 '22 02:09

ColinD