Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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 ...;
}
share|improve this question
    
"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
add comment

2 Answers

up vote 2 down vote accepted

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).

share|improve this answer
    
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
add comment

I've tried to do the same thing quite recently and I got into problems. Take a look at my question here: http://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 ...;
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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