commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Simone Gianni <simo...@apache.org>
Subject Re: [all] Generics and Return Type?
Date Mon, 22 Sep 2008 11:16:22 GMT
Hi all,
sorry for reopening such an old thread, but it's the latest I've found
searching for "generics".

As James say, it is quite a pain to determine types in a generic class. 
I think commons could be a good place for a library that makes this
operation easier, maybe in beanutils since its mission is to "provide
easy-to-use wrappers around [these capabilities | Reflection and
Introspection]", and I'm writing such a "library" (actually classes
wrapping Class, Method etc..) in my Apache Lab.

More in depth explanation follows.

While it is not possible for purely runtime types, like local variables,
it is still possible for subclasses explicitly extending a generic type
with concrete types and for fields declared as non generics to obtain
vital informations about the type of generic fields and generic method
parameters.

What I'm saying is that in both following cases :
  private List<String> names;
  public class People implement List<Person> { }
 
It is possible to determine the fact that the People.add() method will
accept a Person, and the names.get() method will return a String.
Unfortunately, it is quite complex to determine it, cause Sun decided to
use only 4 interfaces, and force the user to make continuous blind casts
between them.

JRE currently seems not to provide an alternative simple solution, nor
using reflection nor introspection. Even worse, given the following
generic class :

public GenericBean<T> {
  private T myGeneric;
  public T getMyGeneric() { return myGeneric; }
  public void setMyGeneric(T v) { myGeneric = v; }
}

Even subclassing it like "PersonBean extends GenericBean<Person>",
Introspection (and so BeanUtils) will return the type of the myGeneric
property as java.lang.Object, but trying to set the property to any
value which is not a Person will cause a ClassCastException at runtime
because of explicit cast in bridging methods (methods which also create
more noise during reflection).

Not to mention if only the getter or only the setter gets overridden in
a subclass: in that case the compiler requires that the "concrete" type
is used, thus making the getters and setter appear as having different
types, and causing problems both in Introspector and BeanUtils.

I had this problem recently in my Apache Lab, and wrote a (simple, not
yet complete nor optimized, but functioning) wrapper around Class and
Method to obtain this informations. It works also in obscure situations
where a generics is extended by a chain of classes and determining the
actual type require recursion on superclasses while remapping all
generic declarations from the "concrete" one up to the generic one.

I don't think it is yet able to handle all possible situations, but I
think it covers that 70% of use cases which represent a good starting
point. The code is already Apache licensed and "junited" and can be
found on the Magma lab svn here
http://svn.apache.org/repos/asf/labs/magma/foundation-basics/src/main/java/org/apache/magma/basics/utils/GenericClass.java
.

While generics are not "the hot buzzword of the month" anymore, usage of
introspection and reflection is gaining more and more importance since
more and more frameworks are depending on it and gaining popularity
(JPA, IOC containers like Spring, alternative serializations like JSON
and so on), and many of them are currently dealing with the generics
problems with custom code.

WDYT?

Simone


James Carman wrote:
> Does anyone have code that can take care of this situation:
>
> List<String> strings = new ArrayList<String>();
>
> Class returnType = getReturnType(strings.getClass(), "get", int.class);
>
> I want the "returnType" to be java.lang.String.  Does anyone have code
> that would return that?  Is it possible?
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>   


-- 
Simone Gianni            CEO Semeru s.r.l.           Apache Committer
MALE human being programming a computer   http://www.simonegianni.it/


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message