为类类型指定泛型

流氓

我有一个基本上可以处理配置类型转换的方法,但是在指定泛型类型(例如List)时,它成为如何处理特定类型的问题。在理想的世界中,例如使用类型见证程序:

List<String> someVal = MyConfig.SOME_VAL.<List<String>>.as(List.class);'

(完整as代码):

/**
 * Attempts to return the {@link Config} value as a casted type. If the
 * value cannot be casted it will attempt to return the default value. If
 * the default value is inappropriate for the class, the method will
 * throw a {@link ClassCastException}.
 * 
 * @since 0.1.0
 * @version 0.1.0
 * 
 * @param <T> The type of the casting class
 * @param c The class type to cast to
 * @return A casted value, or {@code null} if unable to cast. If the passed
 *         class parameter is of a primitive type or autoboxed primitive,
 *         then a casted value of -1 is returned, or {@code false} for
 *         booleans. If the passed class parameter is for {@link String},
 *         then {@link Object#toString()} is called on the value instead
 */
default public <T> T as(Class<T> c) {
    Validate.notNull(c, "Cannot cast to null");
    Validate.isTrue(Primitives.unwrap(c) != void.class, "Cannot cast to a void type");
    Object o = this.get();
    if (o == null) {
        T back = Reflections.defaultPrimitiveValue(c);
        if (back != null) { //catch for non-primitive classes
            return back;
        }
    }
    if (c == String.class) {
        return (T) String.valueOf(o);
    }
    if (c.isInstance(o)) {
        return c.cast(o);
    }
    if (c.isInstance(this.getDefault())) {
        return c.cast(this.getDefault());
    }
    throw new ClassCastException("Unable to cast config value");
}

因此,从本质上讲,这剩下两部分的问题:为什么不能将见证人类型用于类的泛型(例如List(raw)-> List<String>),以及如何在不做多余的转换的情况下支持使用泛型边界检索类?第一点特别让我感到困惑,因为这是完全合法的:

List<String> test = new ArrayList<>();
test = MyConfig.FRIENDLY_MOBS.as(test.getClass());

尽管返回了原始类型的列表

乌伯瓦赫

该行确实是邪恶的(类型擦除/原始类型),因为没有检查任何Collection类型是否真正包含字符串。

test = MyConfig.FRIENDLY_MOBS.as(test.getClass());

我认为最简单的解决方案是编写一个as方法,该方法同时使用集合类型和元素类的类对象。请参见以下示例(在静态范围内,因此必须对其进行调整):

static List<String> words = Arrays.asList("Hello", "Bonjour", "engine");

static public <E, Coll extends Collection<E>> Coll as(Class<? extends Collection> collClass, Class<E> elemClass) {
    if (collClass.isInstance(words)) {
        Collection coll = collClass.cast(words);
        for (Object o : coll)
            if (!elemClass.isInstance(o))
                throw new ClassCastException("BAM");
        return (Coll)coll;
    }

    return null;
}

现在发现以下行为:

final List<String> list = as(List.class, String.class); // works
final List<String> list = as(List.class, Integer.class); // compile error: type check
final List<Integer> list = as(List.class, String.class); // compile error: type check
final List<Integer> list = as(List.class, Integer.class); // ClassCastException

至于其他尝试:iirc Jackson正在进行一些神奇的TypeToken东西,这些东西可以捕获诸如List <String>之类的类型。我认为它滥用了Enum <T>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为类类型指定泛型

来自分类Dev

如何为泛型类指定泛型集合类型?

来自分类Dev

泛型-使用父类在泛型中指定类型

来自分类Dev

无论如何,有没有为泛型类指定可能的类型?

来自分类Dev

Java泛型:如何为泛型类型化的类指定类类型?

来自分类Dev

Java泛型:如何为泛型类型化的类指定类类型?

来自分类Dev

检查类中泛型类型是否为特定类型

来自分类Dev

强制泛型类型参数为类类型?

来自分类Dev

使用反射为泛型类型变量生成lambda类

来自分类Dev

Scala泛型:如何声明类型必须为case类?

来自分类Dev

为复杂的泛型类型创建类或接口

来自分类Dev

无法创建类型为 Map.Entry 的泛型类

来自分类Dev

如何指定泛型类?

来自分类Dev

在泛型类型的泛型类上访问类型参数

来自分类Dev

如何使用泛型返回泛型类的类类型?

来自分类Dev

如果未指定类型参数,为什么Java泛型原始类会擦除对象的所有泛型?

来自分类Dev

访问类型是泛型类的子类型?

来自分类Dev

泛型类型类的正确类型提示

来自分类Dev

C#如何使用类型为“类型”的对象初始化泛型类

来自分类Dev

如何在Scala中为泛型类型提供默认类型类?

来自分类Dev

C#如何使用类型为“类型”的对象初始化泛型类

来自分类Dev

创建泛型类的实例,如何轻松地将类型设置为调用类

来自分类Dev

泛型方法和泛型类中的类型推断

来自分类Dev

Swift:在泛型类中比较泛型类型

来自分类Dev

Swift:在泛型类中比较泛型类型

来自分类Dev

返回泛型而不指定类型参数

来自分类Dev

返回指定类型的泛型 Traversable

来自分类Dev

为什么在泛型类中使用枚举时必须指定类型实参

来自分类Dev

如何获得对具有指定类型的泛型类的构造函数的引用?

Related 相关文章

  1. 1

    为类类型指定泛型

  2. 2

    如何为泛型类指定泛型集合类型?

  3. 3

    泛型-使用父类在泛型中指定类型

  4. 4

    无论如何,有没有为泛型类指定可能的类型?

  5. 5

    Java泛型:如何为泛型类型化的类指定类类型?

  6. 6

    Java泛型:如何为泛型类型化的类指定类类型?

  7. 7

    检查类中泛型类型是否为特定类型

  8. 8

    强制泛型类型参数为类类型?

  9. 9

    使用反射为泛型类型变量生成lambda类

  10. 10

    Scala泛型:如何声明类型必须为case类?

  11. 11

    为复杂的泛型类型创建类或接口

  12. 12

    无法创建类型为 Map.Entry 的泛型类

  13. 13

    如何指定泛型类?

  14. 14

    在泛型类型的泛型类上访问类型参数

  15. 15

    如何使用泛型返回泛型类的类类型?

  16. 16

    如果未指定类型参数,为什么Java泛型原始类会擦除对象的所有泛型?

  17. 17

    访问类型是泛型类的子类型?

  18. 18

    泛型类型类的正确类型提示

  19. 19

    C#如何使用类型为“类型”的对象初始化泛型类

  20. 20

    如何在Scala中为泛型类型提供默认类型类?

  21. 21

    C#如何使用类型为“类型”的对象初始化泛型类

  22. 22

    创建泛型类的实例,如何轻松地将类型设置为调用类

  23. 23

    泛型方法和泛型类中的类型推断

  24. 24

    Swift:在泛型类中比较泛型类型

  25. 25

    Swift:在泛型类中比较泛型类型

  26. 26

    返回泛型而不指定类型参数

  27. 27

    返回指定类型的泛型 Traversable

  28. 28

    为什么在泛型类中使用枚举时必须指定类型实参

  29. 29

    如何获得对具有指定类型的泛型类的构造函数的引用?

热门标签

归档