【问题标题】:How can I tell Java that two "?"s are the same type?我如何告诉 Java 两个“?”是同一类型?
【发布时间】:2018-01-24 19:20:51
【问题描述】:

我目前在这一行遇到编译错误:

chosenState = chosenState.withProperty(property, value);

其中propertyIProperty<?>,值是Comparable<?>withProperty的签名是:

<T extends Comparable<T>, V extends T> IBlockState withProperty(IProperty<T> property, V value);

IProperty 的类型参数是:

IProperty<T extends Comparable<T>>

编译错误是:

chosenState = chosenState.withProperty(property, value);
                         ^
required: IProperty<T>,V
found: IProperty<CAP#1>,Comparable<CAP#2>
reason: inference variable T has incompatible bounds
  equality constraints: CAP#1
  lower bounds: V,Comparable<CAP#2>
where T,V are type-variables:
  T extends Comparable<T> declared in method <T,V>withProperty(IProperty<T>,V)
  V extends T declared in method <T,V>withProperty(IProperty<T>,V)
where CAP#1,CAP#2 are fresh type-variables:
  CAP#1 extends Comparable<CAP#1> from capture of ?
  CAP#2 extends Object from capture of ?

我想通过查找类型 TV 来解决它,其中:

  • IProperty&lt;?&gt; 扩展 IProperty&lt;T&gt;
  • Comparable&lt;?&gt; 扩展 V 扩展 T 扩展 Comparable&lt;T&gt;

一些可以工作的类型参数是&lt;?, ?&gt;,但是?s 都是未知的但类型相同,或者至少第一个? 扩展了第二个。有没有办法告诉编译器?

我知道这两个?是一样的,因为valueIProperty&lt;T extends Comparable&lt;T&gt;&gt;Collection&lt;T&gt; getAllowedValues();方法返回的集合的一个元素。

我知道我可以通过转换为 IPropertyComparable 来解决这个问题,但我想避免使用原始类型。

【问题讨论】:

  • 我不明白你想做什么。请展示实现。
  • 什么是 propertyvalue,在演员表之前?
  • 看起来像X/Y problem。你到底想做什么?
  • @Onheiron:对不起,我在复制行时忘记删除了。这就是我现在正在做的一种解决方法,但我希望它能够工作,而不必将它们转换为原始类型。
  • 如何确定Comparable&lt;?&gt;IProperty&lt;?&gt; 的扩展?

标签: java generics compiler-errors


【解决方案1】:

您必须向编译器保证V 绑定到T

使用通配符,编译器不能保证Comparable&lt;?&gt; 将成为? 的子类型,因为您可以拥有不兼容的String valueIProperty&lt;Integer&gt;

要解决您的问题,您可以创建中间包装器,该包装器将保存 valueproperty 以保证 V extends T 限制并保持对由通配符限制的 Tuple&lt;?, ?&gt; 实例的引用,而不是单独使用 propertyvalue

    public class Tuple<T extends Comparable<T>, V extends T>{
        private IProperty<T> property = null;
        private V value = null;

        public Tuple(IProperty<T> property, V value){
            this.property = property;
            this.value = value;
        }

        public IProperty<T> getProperty() {
            return property;
        }

        public V getValue() {
            return value;
        }
    } 

   <T extends Comparable<T>, V extends T> IBlockState withProperty(Tuple<T, V> t){
        return withProperty( t.getProperty(), t.getValue() );
    }

最后:

    IProperty<String> property = ...;
    String value = ...;

    Tuple<?, ?> t = new Tuple<>(property, value);

    withProperty(t);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    相关资源
    最近更新 更多