2

In a library I am developing I have a factory method that looks a bit like:

public <T> T instantiate(Type targetType) {
    return ...;
}

I am using a type parameterized method to avoid that users of my library have to cast every time they invoke it (that would be the case if I would have chosen to return Object).

Is there any reason this is not a good design choice ?.

I do not like that the programmer can invoke my method like:

String s = instantiate(Integer.class);

Which is clearly wrong.

Unfortunately, the method requires a type and not a class, otherwise I could have written something like:

public <T> T instantiate(Class<T> targetClass) {
    return ...;
}
  • "Unfortunately, the method requires a type and not a class" - why? – Michael Borgwardt Apr 25 '13 at 22:51
  • Hi @Michael. In my problem, the actual type arguments of the type passed as parameter may give an hint on the right way to instantiate the type. – Sergio Apr 26 '13 at 17:35
5

Java generics simply can't do what you want it to do, because Type is not itself parameterized like Class is, and it can't be because it also covers primitive types, which cannot be type parameters. You'd probably also run into problems with the lack of covariance. Adding a second Class parameter is probably the most simple solution.

Java's type system, especially its generics just aren't very powerful, at least compared to languages like Haskell. But it's good enough 99.9% of the time, and I'd rather live with a few edge cases where type safety cannot be guaranteed at compile time than lose myself in esotheric type constructs (there's already more than enough opportunity in Java for that when you use nested generics with wildcards).

  • thanks @Michael, so you think it is not a good idea to leave it like it is now, right ?. Part of my question is if the first alternative is an acceptable solution, or if it is definitely not a good idea to have a method like that from a library provider perspective. – Sergio Apr 27 '13 at 1:04
  • @Sergio: If that type parameter is what the API users will actually have then I think it's fine. If they'll have to construct it first and you don't actually support everything that Type covers, it's probably better to require multiple Class parameters. If you're just worried about the lack of type safety, don't sweat it - there is much worse out there. – Michael Borgwardt Apr 27 '13 at 7:10
2

I've tried to do the same thing quite recently and I got into problems. Take a look at my question here: https://stackoverflow.com/questions/15389994/lazy-class-cast-in-java

Instead, I would add a second parameter to that method, the class object of the type T. Basically, your alternative combined with what you need:

public <T> T instantiate(Type targetType, Class<T> klass) {
    return ...;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.