Marc
Marc

Reputation: 7022

Generics: generic class based on generic class

I'm trying to create a generic service that is based on a class with a generics based collection

public class GenericClass<T> {
   List<T> results;
   public List<T> getResults() {
    return results;
   }
}

Im just not sure how to create a service that is based on this GenericClass and has a concrete implementation of T. I would expect something like

public class ServiceManagerImpl<GenericClass<T>> implements ServiceManager<GenericClass<T>> {
    public GenericClass<T> getMyClass() {
    ...
    }
}

But the compiler doesn't like this. Any ideas how to do this?

Marc

Upvotes: 0

Views: 125

Answers (6)

Sai Ye Yan Naing Aye
Sai Ye Yan Naing Aye

Reputation: 6738

You should try likes this;

     public class ServiceManagerImpl<GenericClass<Object>> implements ServiceManager<GenericClass<Object>> {
          public GenericClass<Object> getMyClass() {
       ...
     }

}

You can replace Object with Integer or String or any data types as you likes.

Upvotes: 0

ohyeahchenzai
ohyeahchenzai

Reputation: 324

I am not sure my answer is legal , but it seems meet your requirement:

public class ServiceManagerImpl<T extends GenericClass> implements ServiceManager<T>
{
        @Override
        public T getMyclass() {
            //do your work here;
        }
}

Although it may have a unchecked warning when I declare this class , but this really does!

ServiceManager<GenericClass<Integer>> manager = new ServiceManagerImpl<GenericClass<Integer>>();//passed

Upvotes: 0

Raman Buzaubakov
Raman Buzaubakov

Reputation: 503

public class ServiceManagerImpl<T extends GenericClass<T>> implements ServiceManager<T extends  GenericClass<T>> {
      public GenericClass<T> getMyClass() {
          ...
      }
}

Upvotes: 0

LiuYan 刘研
LiuYan 刘研

Reputation: 1624

The content between <> is called Type Parameters, and GenericClass<T> is not a valid Type Parameter in declaration.

Quote from java generic guide

A generic class is defined with the following format:

class name<T1, T2, ..., Tn> { /* ... */ }

The type parameter section, delimited by angle brackets (<>), follows the class name. It specifies the type parameters (also called type variables) T1, T2, ..., and Tn.

so, you need to use GenericClass<T> in implementation, not in declaration.

// declaration
public class ServiceManagerImpl<YourGenericType> implements ServiceManager<YourGenericType> {
    public YourGenericType getMyClass() {
    ...
    }
}

// implementation
ServiceManager<GenericClass<Object>> sm = new ServiceManagerImpl<GenericClass<Object>>();

Upvotes: 0

Bohemian
Bohemian

Reputation: 424983

You are close... just pass the T through:

public class ServiceManagerImpl<T> implements ServiceManager<GenericClass<T>> {
    public GenericClass<T> getMyClass() {
    ...
    }
}

Upvotes: 2

Dmitriy Sukharev
Dmitriy Sukharev

Reputation: 1124

I can suggest the following implementation that doesn't break the rules of JLS:

// ServiceManager.java
public interface ServiceManager<E, T extends GenericClass<E>> {
}

// ServiceManagerImpl.java
public class ServiceManagerImpl<E, T extends GenericClass<E>> implements ServiceManager<E, T> {
    public T getMyClass() {
        return null;
    }
}

Upvotes: 0

Related Questions