1

Lets say...

<T, S extends T> void work(final Class<T> type, final S object) {}

or

<T> void work(final Class<T> type, final T object) {}

How can I pass following parameters to work()?

final Class<?> type = <not null> // This is actually an reflection output.
final Object object = <not null>

assert type.isInstance(object); // this is absolutely guaranteed

work(type, type.cast(object)); // compile error; how can I do this?
work(type, object); // compile error; how can I do this?
2
  • I changed the method like this. void work(Class<?> type, Object object) and I put a conditional check for type.isInstance(object). Did I do right? Thank you. Commented May 11, 2011 at 7:50
  • Oh. I thank for all answers. But I can't choose all of them as the accepted answer. I'm sorry. Thank you all Commented May 11, 2011 at 7:59

3 Answers 3

2

You'd need a Class<T> for this to work, but you can get that. Once you have that, you can simply do this:

work(type, type.cast(object));

Now, since you've got a Class<?> you can't simply assign it to a Class<T>, but you can work around this by providing an additional method:

<T> void checkedWork(final Class<T> type, final Object object) {
    work(type, type.cast(object));
}
Sign up to request clarification or add additional context in comments.

7 Comments

I'd add the isInstance check to checkedWork since that'd have to be done anyway.
@Thomas: Class.cast() will throw a ClassCastException if the types don't match at runtime, so I'd say that's even more appropriate than using an assert.
If you want to deal with ClassCastExceptions at runtime, yes you can do that. I'd rather check first and try to avoid ClassCastExceptions at runtime.
@Thomas: true, but for that you'd need correct and complete generics information so that the compiler can decide if it works (in which case you wouldn't need the cast() call. But the decision between assert/cast() is not relevant here, since both only happen at runtime.
Yes, you'd need complete generics information. That's why I talked about a rigid requirement (maybe the wording was inaccurate). Since you don't have the type of the object at compile time, enforcing S extends T doesn't make much sense.
|
2

Change final Class<?> type to final Class<Object> type (or to whatever concrete type you have). In your definition you have S extends T but if you pass in Class<?> you'd get T = ? and the compiler could not check whether Object extends ? (since ? could be anything).

Edit:

Alternatively, change work to <T, S> void work(final Class<T> type, final S object) {}.

4 Comments

@Peter Yes, but his declaration states this as a requirement: S extends T. If this requirement is not that rigid (he's checking for isInstance anyway), then the declaration of work should just contain <T, S>.
How is S extends T more rigid than isInstance?
@Joachim S extends T is not more rigid, but the requirement itself is: The object passed in must be of type T or a subclass. isInstance just moves the check for this requirement to runtime. With isInstance you could just remove the compile time check.
This essentially does the same this as the chosen answer without the addition method declaration and is just as safe, additionally in my case it was <T extends MyClass> as well and i just cast the class object i got to Class<MyClass> instead of Class<? extends MyClass>, +1 from me
1

The compiler cannot check that the object is an instance of type. You can do this at runtime as you have done. The simplest way to get this to compile is to use

final Class type = <not null>

This will give you a warning that the type is unchecked.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.