Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / April 2007

Tip: Looking for answers? Try searching our database.

Generics and reflection

Thread view: 
kelvSYC - 05 Apr 2007 03:02 GMT
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?
Tom Hawtin - 05 Apr 2007 03:20 GMT
> 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
Daniel Pitts - 05 Apr 2007 06:22 GMT
> > I have this really ugly thing regarding generics and reflection (and
> > probably one of those type-erasure weaknesses):
[quoted text clipped - 24 lines]
>
> 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.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.