The required information seems to be there.
// field
private CollectionClass<Integer, Long, Double> cc;
public void testMain() throws Exception
{
ClassInfo info = (ClassInfo)
configuration.getTypeInfo(getClass().getDeclaredField("cc").getGenericType());
while(info.isCollection())
{
printInfo(info);
if(info.getGenericInterfaces() != null)
{
ClassInfo colInfo = info;
while (!colInfo.getName().equals(Collection.class.getName()))
{
InterfaceInfo[] gi = colInfo.getGenericInterfaces();
for (InterfaceInfo ii : gi)
{
if (ii.isCollection())
{
printInfo(ii);
colInfo = ii;
break;
}
}
}
}
if (info.getGenericSuperclass().isCollection())
{
info = info.getGenericSuperclass();
}
else
{
break;
}
}
}
private void printInfo(ClassInfo info)
{
System.out.println((info.isInterface() ? "interface" : "class")
+
": " + info + ", isCol=" + info.isCollection());
TypeInfo[] typeArgs = info.getActualTypeArguments();
if(typeArgs == null)
{
System.out.println("no args");
}
else
{
System.out.println("type args:");
TypeVariable[] typeVars = info.getType().getTypeParameters();
for(int i = 0; i < typeArgs.length; ++i)
{
System.out.println(" " + typeVars[i].getName() + "=" +
typeArgs[i].getName());
}
}
System.out.println("---");
}
public abstract class CollectionClass<T1 extends Object, T2 extends
Object, T3 extends Object>
implements Comparable<T2>, Collection<T1>,
java.util.Comparator<T3>
{
}
The output is
class:
ParameterizedClassInfo(a)7b7072{org.jboss.xml.binding.test.MainTestCase.org.jboss.xml.binding.test.MainTestCase$CollectionClass<java.lang.Integer,
java.lang.Long, java.lang.Double>}, isCol=true
type args:
T1=java.lang.Integer
T2=java.lang.Long
T3=java.lang.Double
---
interface: ParameterizedClassInfo(a)913750{java.util.Collection<T1>},
isCol=true
type args:
E=java.lang.Object
---
Note, that the interface is printed with the T1 variable. And I can get
the value of T1 from the super class. But I can't find out using the API
that T1 is passed to the Collection.
Alexey
Adrian wrote:
On Mon, 2007-07-30 at 14:39 +0200, Alexey Loubyansky wrote:
> That's my problem. How can I find out using the API which parameter is
> passed to the Collection
>
> public abstract class CollectionClass<T1 extends Object, T2 extends
> Object, T3 extends Object>
> implements Comparable<T2>, Collection<T1>,
java.util.Comparator<T3>
> {
> }
>
> Besides that I have to keep track of arguments from sub- to super
> classes. And Collection interface can be extended implemented on
> different levels with different type parameters (but those should belong
> to the same type hierarchy).
> But the main problem I think is the first one above.
That's a very good question. If the class implements
Collection<Whatever> directly, you can get at this
information.
It's just:
for (ClassInfo intf : myClass.getInterfaces())
{
if (intf.getName().equals(Collection.class.getName())
return intf.getActualTypeArguments()[0];
}
But if it is on a superclass, there is no way to get
at this information.
In the main java reflection api:
Class.getGenericSuperClass() returns a ParameterizedType
but from that ParameterizedType there is no route
to get the generic interfaces.
e.g.
public class MyClass extends AbstractCollection<Whatever>
then there's no way to get at the ParameterizedType
Collection<Whatever> that AbstractCollection<Whataver> implements.
What would really be useful would be if there was a
Class.getAllGenericInterfaces();
but that doesn't exist.