-1

I need to get type of generic type. I've already tried following

public abstract class RetrofitRequest<RESULT> extends SpiceRequest<Response<RESULT>> {

    public RetrofitRequest(){
        super(Response<RESULT>.class); //compile time error
    }

    @Override
    public final Response<RESULT> loadDataFromNetwork() throws Exception {
        WebService webService = RestFulWebService.getRestFulWebService();
        return doInBackground(webService);
    }

    protected abstract Response<RESULT> doInBackground(WebService webService) throws Exception;

}

any idea how to get this done? thanks in advance!!!

and SpiceRequest is something like this

public abstract class SpiceRequest<RESULT> implements Comparable<SpiceRequest<RESULT>> {

    public SpiceRequest(Class<RESULT> clazz) {
        ....
    }
}

Thanks!

-supunz

Lakshan Dissanayake
  • 521
  • 1
  • 4
  • 18
  • 1
    Type erasure. You're not going to get it easily. Why doesn't this work for you anyway? What are you actually trying to solve? – Makoto Jun 23 '17 at 20:11
  • because it generates a compile time error in `super(Response.class);` – Lakshan Dissanayake Jun 23 '17 at 20:19
  • What are you trying to achieve with that...? – Makoto Jun 23 '17 at 20:20
  • since i extends my class with `SpiceRequest>`, it needs to pass type of generics to parent constructor.. – Lakshan Dissanayake Jun 23 '17 at 20:22
  • 1
    Actually, you don't. If your parent class is typed, and your child class is typed, then at compile time it should resolve correctly. Perhaps you should include your parent class (and a child class) to better explain your question. – Makoto Jun 23 '17 at 20:23
  • Edit your question with this information, please. – Makoto Jun 23 '17 at 20:26
  • 3
    When you use a `Class` instance as a run-time type token ("RTTT") you generally have to pass it in from the caller of the constructor. As you discovered, a `Class` where `R` is a type parameter (conventionally spelled with a single uppercase letter), won't work. You have to pull it from the type's `class` literal or an instance where the compiler can "see" the specific resolution of the type parameter. Once you do that, then you have the full power of runtime generics. (You can also play games with unchecked casts, but that isn't usually great.) – Lew Bloch Jun 23 '17 at 20:29
  • 1
    The issue is that .class cannot be used on something with a type so no `List.class` but `List.class` is OK –  Jun 23 '17 at 20:34
  • Thanks RC!!! it worked – Lakshan Dissanayake Jun 23 '17 at 20:40

2 Answers2

1

You need to mirror your parent controller in asking for a Class<RESULT>.

public RetrofitRequest(Class<RESULT> clazz){
    super(clazz);
}

The regrettable thing is now that you have to carry that all the way down the inheritance chain, but should you want to instantiate it, you'd need to provide the class too:

RetrofitRequest<String> impl = new RetrofitRequestImpl<String>(String.class);
Makoto
  • 104,088
  • 27
  • 192
  • 230
0

solved myself with the help of RC comment

public abstract class RetrofitRequest<RESULT> extends SpiceRequest<Response<RESULT>> {

    protected RetrofitRequest(){
        super((Class<Response<RESULT>>) (Class<?>) Response.class);
    }

    @Override
    public final Response<RESULT> loadDataFromNetwork() throws Exception {
        WebService webService = RestFulWebService.getRestFulWebService();
        return doInBackground(webService);
    }

    @WorkerThread
    protected abstract Response<RESULT> doInBackground(WebService webService) throws Exception;

}

and https://coderanch.com/t/681438/java/Class-Type-List-java#3196253 just saved my day

Lakshan Dissanayake
  • 521
  • 1
  • 4
  • 18
  • It might not be a good idea to use raw types, but if you use them, you could extend `SpiceRequest>` normally and just call `super((Class) Response.class)`. – Bubletan Jun 23 '17 at 20:44