tags:

views:

48

answers:

6

Hello, I'm looking for a solution to instantiate and return a Vector (or sth comparable) of classes.

My attempt looks like this (Heritage extends SuperClass):

public Vector<? extends SuperClass> getAssignableClasses()
{
Vector<? extends SuperClass> out = new Vector<SuperClass>();
out.add(Heritage.class); //does NOT work, IDE shows error message

return out;
}

The list's declaration seems to be erroneous. I suppose by this I can only add objects to a list, but how can I add classes using generics?

Thanks in advance!

+1  A: 

I have not done this for a while, but isn't 'super' the keyword to use when you need to add stuff? :)

Here is a tutorial :)

willcodejavaforfood
The problem here is that there are no objects to be added but solely classes as it says "out.add(Heritage.class);" I'm looking for a way to create a list of classes
Bernd
A: 

I think the problem is that you tell java to make a vector with Objects of a type derived from Superclass. And then you add a class not an object. A dirty solution would be to make a vector of Class and test while adding if it's a subclass.

kasten
+1  A: 

You are trying to add an instance of Class - that is, Heritage.class. Your Vector only allows subclasses of SuperClass.

You need to add a new Heritage() object, however you construct one of those.

Noel M
+1  A: 

The problem is, you are trying to add a class to the Vector (Heritage.class) instead of an object with the appropriate class. Something as follows should work:

public Vector<? extends SuperClass> getAssignableClasses()
{
  Vector<? extends SuperClass> out = new Vector<SuperClass>();
  out.add(new Heritage()); //this line is changed
                           //add appropriate constructor parameters as necessary
  return out;
}

Update I re-read your question. To return the concrete classes, you will need something as follows (I did not try this):

  public Vector<? extends SuperClass.class> getAssignableClasses()
  {
    Vector<? extends SuperClass> out = new Vector<SuperClass>();
    out.add(Heritage.class); //does NOT work, IDE shows error message
    return out;
  }
Zoltán Ujhelyi
+1  A: 

Or -as others have pointed out- you have to add an instance of Heritage: new Heritage()...

Or you have to declare correctly the Vector in order to store classes instead of instances:

Vector<Class<? extends SuperClass>>

Class<? extends SuperClass> means SuperClass.class or any descendant...

Important: Use List instead of Vector. It's the recomended list interface since Java 1.3 :)

Added: I've checked the code in your comment and it seems to compile ok:

import java.util.Vector;

public class SuperClass {
    public static void main() throws Exception {
        Vector<Class<? extends SuperClass>> vector = new Vector<Class<? extends SuperClass>>();
        vector.add(SuperClass.class);
        vector.add(Heritage.class);
    }

    public Vector<Class<? extends SuperClass>> getAssignableClasses() {
        Vector<Class<? extends SuperClass>> out = new Vector<Class<? extends SuperClass>>();
        out.add(Heritage.class);
        return out;
    }
}

class Heritage extends SuperClass {

}
helios
Yeah, that's what I just found out :-) But still the method signature seems to be wrong: public Vector<Class<? extends BasicComponent>> getAssignableClasses() { Vector<Class <? extends BasicComponent>> out =new Vector<Class <? extends BasicComponent>>(); out.add(ZahnradComponent.class); return out; }
Bernd
You can use ArrayList as implementation (or LinkedList... but ArrayList will suffice most of the time).
helios
+1  A: 

Vector is an old, somewhat deprecated class. I'll use a generic list version instead:

public static List<Class<?>> getAssignableClasses(final Object o){
    final List<Class<?>> list;
    if(o == null){
        list = Collections.emptyList();
    } else{
        list = new ArrayList<Class<?>>();
        Class<?> tmp = o.getClass();
        do{
            list.add(tmp);
            tmp = tmp.getSuperclass();
        } while(tmp != null);
    }
    return list;
}

And as a bonus, here is a method that gathers all assignable interfaces based on the above method:

public static List<Class<?>> getAssignableInterfaces(final Object o){
    final List<Class<?>> result;
    final List<Class<?>> assignableClasses = getAssignableClasses(o);
    if(assignableClasses.isEmpty()){
        result = Collections.emptyList();
    } else{
        final Set<Class<?>> interfaces =
            new LinkedHashSet<Class<?>>(assignableClasses.size() * 2);
        for(final Class<?> clazz : assignableClasses){
            interfaces.addAll(Arrays.asList(clazz.getInterfaces()));
        }
        result = new ArrayList<Class<?>>(interfaces);
    }
    return result;
}

Test:

public static void main(final String[] args){
    final Map<String, String> map =
        new ConcurrentHashMap<String, String>();
    System.out.println(getAssignableClasses(map));
    System.out.println(getAssignableInterfaces(map));
}

Output:

[class java.util.concurrent.ConcurrentHashMap, class java.util.AbstractMap, class java.lang.Object]
[interface java.util.concurrent.ConcurrentMap, interface java.io.Serializable, interface java.util.Map]
seanizer