为什么局部变量会影响类型推断相等约束?

詹斯:

我在理解类型推断中的捕获时遇到问题。我有一些看起来像这样的代码:

import java.util.EnumSet;

class A {
    static enum E1 {
    X
    }

    private static <T extends Enum<T>> EnumSet<T> barEnum(Class<T> x) {
        return null;
    }

    private static void foo1(EnumSet<E1> s, E1 e) {
        EnumSet<E1> x2 = barEnum(e.getClass());
    }

    private static void foo2(EnumSet<E1> s) {
        EnumSet<E1> x = barEnum(s.iterator().next().getClass());
    }
}

编译时会出现两个错误:

Test.java:15: error: method barEnum in class A cannot be applied to given types;
        EnumSet<E1> x2 = barEnum(e.getClass());
                         ^
  required: Class<T>
  found: Class<CAP#1>
  reason: inference variable T has incompatible equality constraints E1,CAP#2
  where T is a type-variable:
    T extends Enum<T> declared in method <T>barEnum(Class<T>)
  where CAP#1,CAP#2 are fresh type-variables:
    CAP#1 extends E1 from capture of ? extends E1
    CAP#2 extends E1 from capture of ? extends E1
Test.java:19: error: method barEnum in class A cannot be applied to given types;
        EnumSet<E1> x = barEnum(s.iterator().next().getClass());
                        ^
  required: Class<T>
  found: Class<CAP#1>
  reason: inference variable T has incompatible equality constraints E1,CAP#2
  where T is a type-variable:
    T extends Enum<T> declared in method <T>barEnum(Class<T>)
  where CAP#1,CAP#2 are fresh type-variables:
    CAP#1 extends E1 from capture of ? extends E1
    CAP#2 extends E1 from capture of ? extends E1
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
2 errors

在尝试理解错误时,我更改foo2为捕获getClass()局部变量中的值以查看实际类型:

private static void foo2(EnumSet<E1> s) {
    // this works
    Class<? extends Enum> c = s.iterator().next().getClass();
    EnumSet<E1> y = barEnum(c);
}

现在,错误消失了,代码被编译了。我不明白引入与表达式类型完全相同的局部变量如何改变类型推断算法并解决问题。

他们是 :

分配s.iterator().next().getClass()给局部变量时,使用的是原始类型- Enum这样可以克服编译错误,但是会收到警告。

如果改用强制转换,则可以在没有局部变量的情况下获得相同的行为:

private static void foo2(EnumSet<E1> s) {
    EnumSet<E1> x = barEnum((Class<? extends Enum>)s.iterator().next().getClass());
}

您可以使用以下方法避免强制转换:

private static void foo2(EnumSet<E1> s) {
    EnumSet<E1> x = barEnum(s.iterator().next().getDeclaringClass());
}

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

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

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么作为值的局部变量的类型会影响函数类型签名中输入变量的类型?

Java:为什么更改局部变量会影响全局变量原始副本?

为什么更改局部变量值会影响全局副本

为什么局部变量会自动更改

为什么局部变量会自我更新?

为什么 printf 会修改以前的局部变量?

Java的10局部变量类型推断的优势?

无法识别局部变量类型推断

我是否打破了Java的局部变量类型推断?

不使用局部变量时为什么会获得EXC BAD ACCESS?

将js函数分配给局部变量后,为什么它们会失败?

为什么此条件(null ||!TryParse)会导致“使用未分配的局部变量”?

为什么默认情况下会初始化局部变量?

为什么将QThread创建为局部变量会导致行为不同

为什么增强的for循环的局部变量必须是局部的?

灿的Java 10的类型推断的局部变量推断无效?

为什么不能将通配符(?)用作参数,字段,局部变量或方法的返回类型?

为什么Dart倾向于忽略局部变量的类型注释?

Scala:变量类型推断会影响性能吗?

为什么解释器调用变量ia局部变量

为什么在case语句中变量不是局部变量?

为什么我们不能用从类型变量未初始化的局部变量访问静态内容?

为什么局部变量不具有默认类型而全局变量具有C?

为什么局部变量不超出范围?

为什么局部变量在Java中是线程安全的

为什么局部变量会在Python中循环

为什么在HashMap.keySet声明局部变量KS()?

为什么lambda对象中的局部变量是const?

装饰器:了解为什么不刷新局部变量