gpt4 book ai didi

java - 动态类型检查匹配类型参数

转载 作者:行者123 更新时间:2023-12-04 08:50:21 24 4
gpt4 key购买 nike

我希望实现一个具有以下签名的方法:

<T> void function(Class<T> clazz, Consumer<T> consumer)
这个函数需要一个 Object obj (其他地方提供),使用 clazz.cast(obj)将其转换为 T ,然后调用 consumer用它。 (基本上,它是 consumer 的守卫。)
这或多或少都很好,我可以写
Consumer<String> c = ...;
function(String.class, c);
不幸的是,以下代码不起作用:
Consumer<List<String>> c = ...;
function(List.class, c);
这是因为 List.class有类型 Class<List> , 不是类 Class<List<String>> .
我可以更改 c 的类型至 Consumer<List> ,但这将与我在其他地方的代码不兼容(而且原始类型无论如何都不好)。
有什么方法可以 (a) 调用 function以某种方式进行类型检查或 (b) 更改 function 的类型签名以某种方式使这种模式起作用?
备注:
  • 我希望尽可能多地保留编译和运行时类型安全。所以,function(Class<?> clazz, Consumer<T> consumer)不会被接受,因为用户很容易提供错误 clazz .并调用为 function((Class<List<String>>)List.class, c)也 Not Acceptable ,因为我可能不小心将其转换为 function((Class<Integer>)List.class, c)
    这个错误的转换甚至不会在运行时被捕获。如果有一个函数可以转换 Class<C<T>>Class<C<U>>但不是到 Class<D> ,那会很酷,但如果没有高阶类型,我就看不到这一点。
  • 我知道类型转换将无法在运行时检查我们是否有 List<String>而不是 List<Integer> .没关系。 (好吧,它不是,但我认为它是最好的
    我们可以期待在 JVM 语言中。)
  • 一切都一样,我更喜欢调用 function 的解决方案。简单(可能使 function 更复杂)因为 function在我的库中定义并由该库的用户使用。
  • 出于好奇,我遇到这个问题的实际代码是 here , Instancefunction .
  • 最佳答案

    仅使用 Class<T> 不可能做您想做的事争论。您需要一个 super type token反而。
    如链接文章中所述,您可以通过以下方式实现此类功能:

    public abstract class TypeToken<T> {

    private final Type type;

    public TypeToken() {
    Type superclass = getClass().getGenericSuperclass();
    type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
    }

    public Type getType() {
    return type;
    }
    }
    在 Java 中,您无法获取有关实例的泛型类型变量的信息,但是您可以获得有关父类(super class)型的泛型类型变量的一些信息。请注意 TypeToken类是抽象的。这是您应该在示例中使用它的方式:
    <T> void function(TypeToken<T> token, Consumer<T> consumer)

    Consumer<List<String>> c = ...;

    function(new TypeToken<List<String>>() { }, c);
    这意味着您正在传递 TypeToken 的子类到你的功能。
    最后,里面 function ,你可以提取一个 Class实例和类型转换一个对象如下:
    Class<T> clazz;
    if (type instanceof ParameterizedType)
    clazz = (Class<T>) ((ParameterizedType) type).getRawType();
    else if (typeU instanceof Class)
    clazz = (Class<T>) type;
    else
    throw new RuntimeException("Error handling omitted");
    T t = clazz.cast(obj);

    关于java - 动态类型检查匹配类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64134450/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com