Java中如何获取lambda方法的返回类型?

问题描述 投票:0回答:1

我正在尝试在我的 Java 代码中获取泛型类型

<T>
的类。我使用阿里巴巴的 FastJSON 进行 JSON 处理。以下是我的代码的关键部分:

来电者:

public Features findFeatureById(BigDecimal id) {
    return mixedCacheService.get(FEATURE, id.toString(), new MixedCacheService.Func<>(() -> featuresDao.selectById(id)));
}

被叫者:

public <T> T get(@NotNull CacheBaseConstants cacheBaseConstants, @NotNull String key, @NotNull Supplier<T> getter) {
    String value = get(cacheBaseConstants, key);
    if ("".equals(value)) {
        return null;
    }
    // How can I get T.class here?
    return Optional.ofNullable(value)
            .map(o -> JSON.parseObject(value, T.class))
            .orElseGet(() -> put(cacheBaseConstants, key, getter));
}

我试图延长

com.alibaba.fastjson.TypeReference

public static class Func<T> extends TypeReference<T> {
    private Supplier<T> supplier;

    public Func(Supplier<T> supplier) {
        super();
        this.supplier = supplier;
    }

    public T get() {
        return supplier.get();
    }
}

我也尝试过使用

getter.supplier.getClass().getGenericSuperclass()
,但它返回了
Object

我想知道如何成功获得

<T>
的课程。任何见解或建议将不胜感激!

java lambda
1个回答
0
投票

你不能。这就是“擦除”的意思。泛型是编译器想象出来的。如果在编译时不可能知道,那就不可能知道。

泛型保留在签名中。换句话说,给定:

class Foo<K, T extends List<K>> {}

然后在运行时你仍然可以得到泛型,但是你能得到的是在编译时的东西。换句话说,你可以从字面上得到:

  • 字母“K”
  • 字母“T”
  • T 延伸
    List<K>
    这一事实。

无法得到的,已被给予,说:

Foo<String, ArrayList<String>> x = new Foo<>();
System.out.println(deriveStatsFrom(x));

deriveStatsFrom
在这里不可能获得
String
ArrayList<String>
。这不是“难”的问题,而是“难”的问题。不,这是一个“不可能”的问题 - 编译器会删除所有这些东西,因此在运行时根本不可能确定这一点。 你提到

com.alibaba.fastjson.TypeReference

这个类是

明确设计来解决这个问题的

要使用它,您

必须

像这样编写类型引用: TypeReference<List<String>> stringListRef = new TypeReference<List<String>>() {};

注意最后奇怪的
{}

这是强制性的
。这创建了一个很小的类,类 do 带有它们签名的泛型。换句话说,上面有很多语法糖: class SomeIrrelevantName extends TypeReference<List<String>> {} TypeReference<List<String>> stringListRef = new SomeIrrelevantName();

因此,
stringListRef.getClass()

让您能够实现它。

这就是 API 希望您做的事情。在您的方法中,您必须添加类型为 

TypeReference<T>

的参数;您粘贴的这个方法

无法知道
,因此您无法解决它。你真的必须不断地告诉自己这一点:如果在编译时你不知道,那么你就不知道。无论在编译时知道什么,都必须制作这个东西并将其传递出去。

© www.soinside.com 2019 - 2024. All rights reserved.