【问题标题】:return nested object with generic input返回具有通用输入的嵌套对象
【发布时间】:2017-12-26 02:03:08
【问题描述】:

我有以下对象初始化。它是 RestfulService 类的一部分。

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

它在课堂上多次使用,但参数不同。例如

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

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

有点罗嗦...我正在尝试创建一个私有方法来返回 ParameterizedTypeReference 对象作为私有方法的一部分。这将减少类中的样板代码和代码重复。我正在努力处理私有方法的语法,特别是泛型的嵌套。

希望通过执行以下操作来获取 ParameterizedTypeReference 对象的实例

pageTypeReference(AnyClassObjectHere.class)

提供一些上下文。我计划在发出休息请求时通过调用私有方法来减少样板代码。所以看起来像下面..

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

更新...

我的尝试看起来像这样。这种作品。然而它现在只是映射到一个通用的链表。对象类型被忽略。

private <T> ParameterizedTypeReference<RestResponsePage<T>> pageTypeReference(Class<T> clazz) {
    return new ParameterizedTypeReference<RestResponsePage<T>>(){};
}

【问题讨论】:

  • 请提供minimal reproducible example。我很难理解您给出的各个代码行是如何组合在一起的。如果您展示一个完整的类,其中包含足够的代码来说明您所询问的内容,这将有很大帮助。
  • 哪个类包含restResponseParam()
  • ParameterizedTypeReference 的全部意义在于它以可以实时使用的方式捕获编译时通用参数,作为防止擦除的措施。如果不提及整个通用“样板”,您将无法从中获得正确的类型。
  • @Code-Apprentice 感谢您的反馈。我已经对问题进行了更改。希望这能让它更容易理解。
  • @RealSkeptic 我在尝试做不可能的事吗?

标签: java generics boilerplate


【解决方案1】:

注意clazzName 是一个变量,而不是一个类型。这意味着您不能将其用作模板参数。例如,由于您将ScanDto.class 传递给它,因此您应该将其声明为Class&lt;T&gt; 而不仅仅是T。您可以使用反射来创建T 类型的实例。

【讨论】:

    【解决方案2】:

    您的私有方法在语法上不正确 - 方法名称是什么?(restResponseParampageTypeReference),预期的返回类型是什么?(T 或 @987654325 @)。现在,我假设您知道这些问题的答案,但只是得到了语法错误的代码。因此,我编写了一个并行示例来展示您可能想要实现的目标(我的理解 - return ParameterizedTypeReference&lt;RestResponsePage&lt;T&gt;&gt; instance from T)可以这样做。

    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.

    你真的不需要 Class 来创建一个实例,除非你想直接用 T 反射性地做一些事情。

    【讨论】:

    • 我认为您错过的部分是 ParameterizedTypeReference 是一个类型标记 - 它用于获取在运行时提供正确通用参数的 Type 对象。这用于补偿类型擦除。
    • @RealSkeptic :那是因为它不是标准 Java API 的一部分,而是 Spring(我只是搜索了它)。但是,是的,看起来是这样。但我认为答案应该仍然有效。
    • 不,我不这么认为。因为如果你传递的T 包含类型参数,则根本没有保存任何样板。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-24
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多