Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Reflection to get Method's Generic Type

I'm trying to create a service container, and want to know how to reflect the type used when the method is called. See below:

public class ServiceContainer {

   HashMap<Type, Object> services;

   public ServiceContainer() {
      services = new HashMap<Type, Object>();
   }

   public <T> void addService(Type t, T object) {
      services.put(t, object);
   }
   public <T> void addService(T object) {
      Type type = typeof(T);
      services.put(type, object);
   }
}

I'd prefer to use the second addService, but if this isn't possible, it's something to fall back on.

EDIT: I think I found a solution for addService, but now there's another method that can't be solved in the same way:

public class ServiceContainer {
   HashMap<Class, Object> services;

   public ServiceContainer() {
      services = new HashMap<Class, Object>();
   }

   public <T> void addObject(T object) {
      Class type = object.getClass();
      services.put(type, object);
   }
   public <T> boolean containsService() {
   }
   public <T> T getService() {
      services.get(
         ServiceContainer.class.getMethod( "getService", null )
            .getGenericParameterTypes()[0] );
   }
}

I'm kind of shooting in the dark now, I should go brush up on some documentation...

like image 917
Caleb Jares Avatar asked Sep 08 '26 05:09

Caleb Jares


1 Answers

The second addService is not possible unless you map on the class name (instead of Type) - e.g.

public class ServiceContainer {
 HashMap<Class, Object> services;

 public ServiceContainer() {
     services = new HashMap<Class, Object>();
 }

 public <T> void addService(Class<T>, T object) {
     services.put(t, object);
 }
 public <T> void addService(T object) {
     Class type = object.getClass();
     services.put(type, object);
 }
}

the reason typeOfT() doesnt work is because java generics are "erased" after compilation. It is really only 'syntactic sugar' that the ocmpiler uses to check for obvious errors in type assignments.

edit: since the question changed: to implement the containsService method:

public boolean containsService(String classname) {
   return services.get(Class.forName(classname)) != null;
}

I'd say, given what you're doing is quite common, have a look into how you might use a dependency injection library to perform your service registrations and retrieval. I hear good things about Spring , and google Guice.

like image 127
Chii Avatar answered Sep 09 '26 19:09

Chii



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!