0

I have the following object initialization. Its part of a RestfulService class.

ParameterizedTypeReference<RestResponsePage<ScheduledScanDto>> ptr =
            new ParameterizedTypeReference<RestResponsePage<ScheduledScanDto>>(){};

It is used several times in the class but with different params. e.g.

ParameterizedTypeReference<RestResponsePage<ScanDto>> ptr =
            new ParameterizedTypeReference<RestResponsePage<ScanDto>>(){};

or

ParameterizedTypeReference<RestResponsePage<SomeOtherObject>> ptr =
            new ParameterizedTypeReference<RestResponsePage<SomeOtherObject>>(){};

Its a bit wordy... I am trying to create a private method to return the ParameterizedTypeReference object as part of a private method. This will reduce boilerplate code in the class and code duplication.. I'm struggling with the syntax on the private method, in particular the nesting of generics.

Would like to get an instance of ParameterizedTypeReference objects by doing the following

pageTypeReference(AnyClassObjectHere.class)

To give some context. I plan to reduce boilerplate code by calling the private method when making a rest request. So would look like the following..

private List<ScanDto> methodMakeScanRequest{
  List<ScanDto> = restTemplate.exchange("/localhost/scans-url",HttpMethod.GET, pageTypeReference(ScanDto.class)).getBody()
}

Update...

My attempt looks like this. This kind of works. However it now just maps to a generic linkedlist. The object type is ignored.

private <T> ParameterizedTypeReference<RestResponsePage<T>> pageTypeReference(Class<T> clazz) {
    return new ParameterizedTypeReference<RestResponsePage<T>>(){};
}
Robbo_UK
  • 11,351
  • 25
  • 81
  • 117
  • Please provide a [mcve]. I am having difficulty understand how the individual lines of code you have given go together. It will help a lot if you show a complete class with just enough code to illustrate what you are asking about. – Code-Apprentice Jul 20 '17 at 11:43
  • Which class contains `restResponseParam()`? – Code-Apprentice Jul 20 '17 at 11:47
  • 2
    The whole point of a `ParameterizedTypeReference` is that it captures the compile-time generic arguments in a way that they can be used in real time, as a measure against erasure. Without mentioning the entire generic "boilerplate", you won't get a proper type from it. – RealSkeptic Jul 20 '17 at 11:51
  • @Code-Apprentice thanks for the feedback. I have made changes to the question. Hopefully this makes it easier to understand. – Robbo_UK Jul 20 '17 at 12:31
  • @RealSkeptic am i trying to do the impossible? – Robbo_UK Jul 20 '17 at 12:37
  • [Guava `TypeToken`](http://google.github.io/guava/releases/snapshot/api/docs/com/google/common/reflect/TypeToken.html#TypeToken-java.lang.Class-) can do something like this. Most of the other type tokens that I've seen can't. It sounds like you're using Spring `ParameterizedTypeReference` which can't. See also https://stackoverflow.com/a/21988799/2891664. – Radiodef Jul 20 '17 at 14:28

2 Answers2

1

Note that clazzName is a variable, not a type. This means that you cannot use it as a template parameter. Since you are passing ScanDto.class to it, for example, you should declare it as Class<T> rather than just T. You can use reflection to create instances of type T.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
0

Your private method is syntactically incorrect - what is the method name?(restResponseParam or pageTypeReference), what is the intended return type?(T or ParameterizedTypeReference<RestResponsePage<T>>). Now, I assume that you know answer to those questions but just ended up with syntactical incorrect code. So, I have written up a parallel example to show how what you may have wanted to achieve(my understanding - return ParameterizedTypeReference<RestResponsePage<T>> instance from T) can be done so.

class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        Ideone ide = new Ideone();
        SampleClass<String> s = ide.getInstance();
        s.printType(String.class);
    }

    private <T> SampleClass<T> getInstance(){
        return new SampleClass<T>(){};
    }

    private static class SampleClass<T>{

        public void printType(Class<T> clazz){
            System.out.println("Type: " + clazz.getSimpleName());
        }
    }
}

Demo here.

You don't really need Class to create an instance unless you want to do something reflectively with T directly.

Manish Kumar Sharma
  • 12,982
  • 9
  • 58
  • 105
  • I think the part that you missed is the fact that `ParameterizedTypeReference` is a type token - it is used in order to get a `Type` object that provides the correct generic arguments in run time. This is used to compensate for type erasure. – RealSkeptic Jul 20 '17 at 12:49
  • @RealSkeptic : That's because it isn't part of Standard Java APIs but Spring(I just searched for it). But, yeah, so it seems. But the answer should still work I think. – Manish Kumar Sharma Jul 20 '17 at 12:56
  • No, I think not. Because if the `T` you pass includes the type parameters, no boiler plate has been saved at all. – RealSkeptic Jul 20 '17 at 12:59