Java 泛型的统一参数传递和类型安全

Uniform parameters passing and typesafety with Java generics

因为我经常需要处理随机化,所以我想制作一个 class 来方便地将我通常需要的所有这些功能分组。其中,我想到了一个通用的 fromPool() 函数,给定可变数量的对象,return 随机选择其中一个。当然,我必须结合使用可变参数和泛型,我刚刚发现这可能是一个很大的禁忌,具体取决于情况(我怀疑我的情况就是其中之一)。 这是代码:

abstract public class RandomGenerator {

    public static int fromRange(int min, int max) {

        return (int) (Math.random() * (max + 1 - min)) + min;
    }

    public static <T> T fromPool(T ... pool) {

        return pool[fromRange(0, pool.length - 1)];
    }
}

问题是我当然可以传递给 fromPool() 不同种类的对象,使 return 类型极其可变。因此,例如,我可以这样做:

int n = (int) RandomGenerator.fromPool("String", 6);

这将一直有效,直到 fromPool() 不 return "String",然后导致抛出此异常。

Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap') at Test.main(Test.java:109)

这是我想知道的:

1) 泛型和可变参数组合时出现的"Type safety: Potential heap pollution via varargs parameter pool"警告是指这个吗?还有更多吗?

2) 有没有一种方法可以限制泛型效应,这样您就无法将彼此不兼容的对象传递给同一个函数调用?基本上是某种自动的、横向的超载(我觉得我在要求月亮)?

3) 实际上我之前写过一个不太通用的 fromPool() 版本,它只处理 Number 对象。

public static <N extends Number> N fromPool(N ... pool) {

    return pool[fromRange(0, pool.length - 1)];
}

与我最初的看法相反,它结束了这个版本也是不安全的,因为虽然在原始类型之间进行转换不会产生任何问题,但在各种包装器 classes 之间进行转换是不可能的,所以导致再次出现 ClassCastExceptions。有没有办法调整这个版本以至少让这个版本安全?

非常感谢您的见解:)

您可以试试下面的方法。

RandomGenerator.<String>fromPool("String", "Something");

通过这样做,您将明确指定该函数调用的通用对象类型。而且你不需要转换你的 return 值,因为泛型类型是显式声明的。

当您不指定通用对象类型时,它将被推断为 java.lang.Object