当前位置: 首页 > 面试题库 >

将运行时解析的参数传递给具有多个绑定类型的方法,编译错误

陶柏
2023-03-14
问题内容

我有一个看起来像这样的方法:

public static <T extends Enum<T> & Marshallable> String foo(Collection<T> collection, Class<? extends Marshallable>... marshallables);

因此,我期望传递的集合是实现Marshallable接口的Enum。如果我在运行时具有具体的Enum类型,则可以正常工作,但是我编写了一个测试方法,该方法从类对象动态创建一个Enum列表(实现Marshallable),并且无法将此列表传递给上面的方法。

@Test
public void fooTest() {
...
if (clazz.isEnum()) { // collection enum xml
    List<? extends Enum<? extends Marshallable>> enumList = (List<? extends Enum<? extends Marshallable>>) Arrays.asList(clazz.getEnumConstants());
--> String enumListXml = foo(enumList, clazz);
...

标记的行将给出编译错误。我不知道如何在不更改方法签名的情况下传递列表。


问题答案:

您需要对泛型辅助方法使用未经检查的演员表:

private static <T extends Enum<T> & Marshallable> void fooHelper(Class<? extends Marshallable> type) {
    if (type.isEnum()) {

        //This is safe because of the isEnum check, and we don't return any
        //type with T (important because the caller can specify what T is).
        @SuppressWarnings("unchecked")
        final Class<T> enumType = (Class<T>)type;

        final List<T> enumConstants = Arrays.asList(enumType.getEnumConstants());
        foo(enumConstants);
    }
}

您的版本不工作的原因是因为T extends Enum<T> & MarshallableT递归的约束-
这只能与类型的参数来表示。中的通配符类型参数? extends Enum<? extends Marshallable>不再指定该关系。

警告: 务必fooHelper不要返回包含的类型,T因为这可能导致堆污染。例如:

private static <T extends Enum<T> & Marshallable> List<T> unsafeFooHelper(Class<? extends Marshallable> type) {
    if (type.isEnum()) {

        //no longer safe!
        @SuppressWarnings("unchecked")
        final Class<T> enumType = (Class<T>)type;

        return Arrays.asList(enumType.getEnumConstants());
    }
    return Collections.emptyList();
}

enum Enum1 implements Marshallable { ONE, TWO }

enum Enum2 implements Marshallable { A, B }

...

//caller lies about what T is:
List<Enum2> enumConstants = Main.<Enum2>unsafeFooHelper(Enum1.class);

//sometime later...
Enum2 enumConstant = enumConstants.get(0); //ClassCastException


 类似资料:
  • 问题内容: 是否可以使用数据绑定库将自定义参数传递给方法?我有需要使用onClickListener的布局xml文件: 我在这里有我的点击处理程序代码: 是否可以将我的CategoryViewModel对象从xml传递到单击处理程序? 问题答案: 您可以使用lambda表达式并将视图作为参数传递。 如果需要视图,也可以通过以下方法传递它:

  • 问题内容: 问题摘要: 我想将具有类型参数(例如)的类作为类型参数传递给泛型方法。 假设我有一个方法: 当然,此方法对于任何类型的类都可以正常使用。我可以这样调用该方法,例如: 问题: 我发现我不能这样做: 从句法上讲,这显然是无效的。但是,我不确定如何实现这样的目标。我当然可以通过,但是泛型类型的添加使其在语法上不再有效,并且我想不出解决方法。 唯一的直接解决方案是这样的事情(看起来很愚蠢):

  • 问题内容: 方法context.getBean(name,user)的文档说 允许指定显式构造函数参数/工厂方法参数 但是无论我做什么(尝试一切),使用最合理的设置在初始化期间加载Bean时都会得到以下信息: 注释说可以做到的,但是如果您在该bean的xml定义中指定构造函数参数,则失败。 问题答案: 在javadoc中说: args-在使用静态工厂方法的显式参数创建原型时使用的参数。 因此,be

  • 我想更好地了解当Java编译器遇到对如下方法的调用时会发生什么。 我很清楚,没有类型

  • 问题内容: 在我的我有一个按钮。我想通过在方法中传递多个参数来为其添加动作。 问题答案: 也许你可以做这样的事情 根据您的要求创建标签值并保持其完整性。

  • 问题内容: 在采用可变数目从该给出的函数被调用iterables的。 如果我有一个生成元组的生成器,这些元组通常在原位打开,该如何命名? 以下代码不起作用,因为每个生成的元组均作为map的不同参数给出: 没有生成器,要映射的所需参数可能如下所示: 问题答案: 您需要删除的电话: 这将调用,时间,应在何处接受一个参数。 在Linux上 ,如果要接受两个参数,则可以使用lambda调用,例如: