我怎么能告诉Java两个"?" s是同一类型的?

时间:2018-01-24 19:20:51

标签: java generics compiler-errors

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

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<?>扩展IProperty<T>
  • Comparable<?>延伸V延伸T延伸Comparable<T>

一些可行的类型参数可能是<?, ?>,但?两个都是未知但类型相同,或者至少第一个?扩展了第二个?。有没有办法告诉编译器?

我知道这两个value是相同的,因为Collection<T> getAllowedValues();IProperty<T extends Comparable<T>>IProperty方法返回的集合的元素。

我知道我可以通过转换为Comparable[{"email":"example@test.com","timestamp":1516820089,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"processed","category":"cat facts","sg_event_id":"FDl9L7nP4zJXgLYUGhqqoA==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0"}, {"email":"example@test.com","timestamp":1516820089,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"deferred","category":"cat facts","sg_event_id":"jbtTInm9Pej80gzRXRg9Pg==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0","response":"400 try again later","attempt":"5"}, {"email":"example@test.com","timestamp":1516820089,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"delivered","category":"cat facts","sg_event_id":"XUBvHRS8T0eD_Eea8IECDA==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0","response":"250 OK"}, {"email":"example@test.com","timestamp":1516820089,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"open","category":"cat facts","sg_event_id":"Wp2888u5ZaJX7Pd-_DbFpA==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0","useragent":"Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)","ip":"255.255.255.255"}, {"email":"example@test.com","timestamp":1516820089,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"click","category":"cat facts","sg_event_id":"7iXIm9S5SAuhRmoy4QIZZg==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0","useragent":"Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)","ip":"255.255.255.255","url":"http://www.sendgrid.com/"}, {"email":"example@test.com","timestamp":1516820089,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"bounce","category":"cat facts","sg_event_id":"3HJSeIIA2FzBjQxXvlf2hQ==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0","reason":"500 unknown recipient","status":"5.0.0"}, {"email":"example@test.com","timestamp":1516820089,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"dropped","category":"cat facts","sg_event_id":"8acL8P-wxlb0CJoxBEjYuQ==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0","reason":"Bounced Address","status":"5.0.0"}, {"email":"example@test.com","timestamp":1516820089,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"spamreport","category":"cat facts","sg_event_id":"cgn6ggkYz1S7XT5D5nRo9w==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0"}, {"email":"example@test.com","timestamp":1516820089,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"unsubscribe","category":"cat facts","sg_event_id":"suFV8ITF-9ND3j1SrlW-fA==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0"}, {"email":"example@test.com","timestamp":1516820089,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"group_unsubscribe","category":"cat facts","sg_event_id":"KljxrqIWTvF0mEshFKnw1Q==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0","useragent":"Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)","ip":"255.255.255.255","url":"http://www.sendgrid.com/","asm_group_id":10}, {"email":"example@test.com","timestamp":1516820089,"smtp-id":"\u003c14c5d75ce93.dfd.64b469@ismtpd-555\u003e","event":"group_resubscribe","category":"cat facts","sg_event_id":"F7oTvsqxOIQyRWyLJeXIjA==","sg_message_id":"14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0","useragent":"Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)","ip":"255.255.255.255","url":"http://www.sendgrid.com/","asm_group_id":10}] 来解决这个问题,但我想避免使用原始类型。

1 个答案:

答案 0 :(得分:3)

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

使用通配符时,编译器无法保证Comparable<?>将成为?的子类型,因为您可能String valueIProperty<Integer>不兼容。

要解决您的问题,您可以创建保留valueproperty的中间包装器,以保证V extends T限制,并保持对通配符限制的Tuple<?, ?>实例的引用,而不是单独的使用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);