2015-06-03 75 views
3

我有方法的签名如下如何将我的类传递给类的通用规范?

public abstract class AbstractFilterParametersWithSpecificationSorting<T> extends AbstractFilterParameters 
... 

public void registerOrderSpecification(final String key, final Class<? extends OrderSpecification<T>> spec) { 
... 

我传递以下

this.registerOrderSpecification(
      AbstractActivityLogWithSiteUser.Index.USER_FULL_NAME, 
      SortActivityLogUserOrderSpecification.class); 

其中有此类的定义

public class SortActivityLogUserOrderSpecification<AL extends AbstractActivityLogWithSiteUser<?>> 
    extends AbstractOrderSpecification<AL> implements OrderSpecification<AL> 

这里就是javac不喜欢(IDEA认为它应该可以工作,但IDEA在Java 8上运行,代码必须在Java 7上编译)

Error:(12, 21) java: method registerOrderSpecification in class com.myapp.service.principal.AbstractFilterParametersWithSpecificationSorting<T> cannot be applied to given types; 
required: java.lang.String,java.lang.Class<? extends com.myapp.specification.OrderSpecification<AL>> 
found: java.lang.String,java.lang.Class<com.myapp.repository.activitylog.specification.SortActivityLogUserOrderSpecification> 
reason: actual argument java.lang.Class<com.myapp.repository.activitylog.specification.SortActivityLogUserOrderSpecification> cannot be converted to java.lang.Class<? extends com.myapp.specification.OrderSpecification<AL>> by method invocation conversion 

我可以施放吗?或者我在某处丢失了一些问号?

+0

猪头...名字太长。先简化他们? – ZhongYu

回答

0

所以我的答案被记住,催生了钻石<>运营商的Java 7投诉的启发,并支持8

得到改善你为什么要编写

List<Foo> foos = new ArrayList<Foo>(); 

List<Foo> foos = Lists.newArrayList(); 

只是工作。当然,这催生了钻石操作

List<Foo> foos = new ArrayList<>(); 

所以我写了一个方法来包装我的类参数

protected <E extends OrderSpecification<T>> Class<E> java7classReturnType(Class<E> clazz) { 
    return clazz; 
} 

,并呼吁这将正常工作

Class<? extends OrderSpecification<OrganizationActivityLog>> clazz 
      = this.java7classReturnType(SortActivityLogUserOrderSpecification.class); 
    this.registerOrderSpecification(AbstractActivityLogWithSiteUser.Index.USER_FULL_NAME, clazz); 
} 
0

我尝试了你的代码,然后开始简化它,以得到一个小例子,显示相同的问题。我终于得到这个(简单得多)代码:

abstract class MyList<T> implements java.util.List<T> { 
} 

public class TestGenerics2<T> { 

    public void processListClass(final Class<? extends java.util.List<T>> spec) { 
    } 

    public void tryIt() { 
     this.processListClass(MyList.class); 
    } 

} 

生成此错误:

TestGenerics2.java:11: processListClass(java.lang.Class<? extends java.util.List<T>>) in TestGenerics2<T> cannot be applied to (java.lang.Class<MyList>) 

我想你应该将它转换(或重构你的代码,这样你就不需要那么通用的复杂性)。

Jon Skeet once said

Sometimes Java generics just doesn't let you do what you want to, and you need to effectively tell the compiler that what you're doing really will be legal at execution time.

+0

是的,除了我找到了一种方法使其工作,所以放弃不是解决方案 – xenoterracide