Generics and reflection

K

kelvSYC

I have this really ugly thing regarding generics and reflection (and
probably one of those type-erasure weaknesses):

Suppose I have this:
public interface Delegate<Ret, T> {
public Ret doStuffWith(T t);
}

I want to make a special kind of delegate:
public class FieldDelegate<Ret, T> implements Delegate<Ret, T> {
private String fieldName;
//...
}

The idea is that in doStuffWith() in the FieldDelegate, I'd grab and
return a (public) field through reflection. Having said that, though,
I think I may have hit a few problems:

1. I don't know what the Ret class is - ever. (How I hate type-
erasure for this...)
2. With this structure, the only time I can get the T class is in
doStuffWith() (ie. t.getClass()), which means I have to check the
validity of the field name every time I call doStuffWith(). Fine, so
I change it to

private Field field;
public FieldDelegate(String fieldName, Class<Ret> retClass, Class<T>
tClass); // Might as well fix the first issue

so that the check is in the constructor. With this, I can check
whether class T has a field with the name fieldName and whether the
type of the field is assignable to the returning class (easy enough),
but now I have another two issues:

1. I don't know the access level of the field. Calling doStuffWith()
may still throw some kind of access violation exception (from
field.get(t)). I don't know how to catch that in the constructor (the
check's done in the constructor so that I don't have to check in
doStuffWith()).
2. I now have to pass in the class objects in the constructor (which
ideally you don't want to do), which seems a bit redundant (but given
type erasure, I guess necessary).

I guess this is one of those times where you wished you had some
syntactic-sugar for T.class, standing for some hidden Class<T>
parameter that's passed in. Anyways, is there any way of getting
around these two issues?
 
T

Tom Hawtin

kelvSYC said:
I have this really ugly thing regarding generics and reflection (and
probably one of those type-erasure weaknesses):

Are you sure you want to be using reflection at all? Reflection should
be kept for extra special occasions. It's generally a bad idea.
1. I don't know the access level of the field. Calling doStuffWith()
may still throw some kind of access violation exception (from
field.get(t)). I don't know how to catch that in the constructor (the
check's done in the constructor so that I don't have to check in
doStuffWith()).

Check the field type in the constructor. You can satisfy Java's checked
exception mechanism (which can only follow a limited set of rules) by
rethrowing exceptions from the method wrapped in an unchecked exception
(an Error).
2. I now have to pass in the class objects in the constructor (which
ideally you don't want to do), which seems a bit redundant (but given
type erasure, I guess necessary).

Well, you are doing some messy stuff. Using a static creation method
would help a little. But it's what, for instance,
AtomicReferenceFieldUpdater has to do.

Just to reiterate, reflection is unlikely to be a good answer.

Tom Hawtin
 
D

Daniel Pitts

Are you sure you want to be using reflection at all? Reflection should
be kept for extra special occasions. It's generally a bad idea.


Check the field type in the constructor. You can satisfy Java's checked
exception mechanism (which can only follow a limited set of rules) by
rethrowing exceptions from the method wrapped in an unchecked exception
(an Error).


Well, you are doing some messy stuff. Using a static creation method
would help a little. But it's what, for instance,
AtomicReferenceFieldUpdater has to do.

Just to reiterate, reflection is unlikely to be a good answer.

Tom Hawtin

To iterate again, reflection is usually (not always) a bad design
decision... I would say the only good reason to use it is if you are
creating a "framework" (JUnit, Spring, Hibernate, etc... all use
reflection in a good way), or an IDE/developers tool.

Anyway, the alternative to what your doing is to create an interface
Delegate (like you do) and then write concrete version of it for the
fields you need to delegate to. That way, you know exactly whats
going on at compile time, no run-time trickery involved.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Trouble with reflection 0
Problem with reflection in C# 4
generics puzzle 57
Generics 24
Hairy generics question 29
Generics and reflection 4
Generics in return types 2
Generics Amanuensis? 2

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top