【问题标题】:Component that checks if objects of one java.lang.reflect.Type can be casted to another?检查一个 java.lang.reflect.Type 的对象是否可以转换为另一个的组件?
【发布时间】:2012-05-03 13:06:14
【问题描述】:

Java 公开了泛型类型信息,例如通过接口java.lang.reflect.Type及其子接口(ParameterizedType、WildcardType)在运行时获取字段类型。

有谁知道我在哪里可以找到一个组件,该组件可以确定一种类型的对象是否可以转换为另一种类型,例如如果 Set<Object> 可以转换为 SetComparator<User> 可以转换为 Comparator<? extends Object>

该解决方案应该适用于由java.lang.reflect.Type 表示的类型信息,而不仅仅是Classes,并且应该考虑泛型,即List<Integer> 不应转换为List<Object>

问候, 乔辰

【问题讨论】:

    标签: java generics


    【解决方案1】:

    【讨论】:

    • 我想指出的是,使用 TypeUtils.isAssignable(...) 不会让您检查安全向下转换。例如,从 Collection 到 List 的强制转换是完全安全的,但 Collection 不能“分配”给 List。最初的问题暗示 isAssignable 就足够了,但始终使用“cast”这个词,所以我认为值得一提。
    • 认为如果其中一个可以分配给另一个,您可以从A 转换为B
    • A := List<Integer>B := Collection<? extends Number>A 可分配给B,但从BA 的转换将是未经检查的,因此是不安全的。
    • @BenSchulz 运行System.err.println(TypeUtils.isAssignable(Collection.class, List.class)); System.err.println(TypeUtils.isAssignable(List.class, Collection.class)); 打印false true。我可以安全地将 List 转换为 Collection,但不能反过来。我不明白这是什么问题。
    • @GuillaumePolet 您可以将Collection<X> 类型的值转换为List<X>,然后转换要么失败(可能是HashSet<X>)要么成功,因为该值为@987654337 @。所有演员真正检查的是该值是List(原始类型),但如果它是List,那么它不可能是List<Y>Y != X,因为任何类都只能实现任何给定接口的一个参数化(此处为Collection)。这意味着强制转换是安全的(强制转换之前没有堆污染 => 之后没有堆污染)。
    【解决方案2】:

    Guava's TypeToken 正是针对这个问题而设计的。它旨在替代泛型感知的Class。 (披露:我为 Guava 做出了贡献。)

    【讨论】:

    • 看了两者之后,我觉得我更喜欢 Guava 的方法。当然,这纯粹是主观的。
    • 你应该自己决定,所以也看看 Guillaume 的回答。
    【解决方案3】:
    if (clazz.isAssignableFrom(otherClazz))
    {
        return true; 
    }
    

    【讨论】:

    • 这仅适用于Class 对象,不适用于Type,并且不考虑泛型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 2021-02-25
    • 2010-09-17
    • 2011-06-07
    • 2020-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多