如何将我的 class 传递给 class 的通用规范?
How can pass my class to the generic specification of the class?
我有以下方法签名
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 );
具有此 class 定义
public class SortActivityLogUserOrderSpecification<AL extends AbstractActivityLogWithSiteUser<?>>
extends AbstractOrderSpecification<AL> implements OrderSpecification<AL>
这里是javac
不喜欢的地方(IDEA认为应该可以,但是IDEA在Java8上是运行,代码必须在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
我可以投吗?还是我在某处遗漏了一些问号?
我尝试了您的代码,然后开始简化它以获得一个显示相同问题的较小示例。我终于得到了这个(更简单的)代码:
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.
所以我的回答是受到了 Java 7 中产生钻石 <>
运算符的抱怨的启发,并且支持在 8 中得到了改进。
为什么要写
List<Foo> foos = new ArrayList<Foo>();
当
List<Foo> foos = Lists.newArrayList();
将正常工作。这当然催生了钻石运营商
List<Foo> foos = new ArrayList<>();
所以我写了一个方法来包装我的 class 参数
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 );
}
我有以下方法签名
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 );
具有此 class 定义
public class SortActivityLogUserOrderSpecification<AL extends AbstractActivityLogWithSiteUser<?>>
extends AbstractOrderSpecification<AL> implements OrderSpecification<AL>
这里是javac
不喜欢的地方(IDEA认为应该可以,但是IDEA在Java8上是运行,代码必须在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
我可以投吗?还是我在某处遗漏了一些问号?
我尝试了您的代码,然后开始简化它以获得一个显示相同问题的较小示例。我终于得到了这个(更简单的)代码:
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.
所以我的回答是受到了 Java 7 中产生钻石 <>
运算符的抱怨的启发,并且支持在 8 中得到了改进。
为什么要写
List<Foo> foos = new ArrayList<Foo>();
当
List<Foo> foos = Lists.newArrayList();
将正常工作。这当然催生了钻石运营商
List<Foo> foos = new ArrayList<>();
所以我写了一个方法来包装我的 class 参数
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 );
}