Java 泛型类和泛型方法
我正在为我的java项目开发一个分页系统,我想让它对我的各种JPA模型通用 问题是(据我所知),如果我使用泛型,我将不得不以某种方式转换返回的最终值来处理它。我怎样才能避免呢 以下是我到目前为止的代码(绝对不是通用的!)Java 泛型类和泛型方法,java,generics,pagination,playframework,Java,Generics,Pagination,Playframework,我正在为我的java项目开发一个分页系统,我想让它对我的各种JPA模型通用 问题是(据我所知),如果我使用泛型,我将不得不以某种方式转换返回的最终值来处理它。我怎样才能避免呢 以下是我到目前为止的代码(绝对不是通用的!) 公共接口分页器{ 公共无效设置限制(整数限制); 公共页面(整型页面); } 公共类PicturesPaginator实现Paginator{ 私有整数限制=10; 私有查询; 私人长数量; 公共PicturesPaginator(字符串查询、对象…参数){ this.quer
公共接口分页器{
公共无效设置限制(整数限制);
公共页面(整型页面);
}
公共类PicturesPaginator实现Paginator{
私有整数限制=10;
私有查询;
私人长数量;
公共PicturesPaginator(字符串查询、对象…参数){
this.query=Picture.find(查询,参数);
this.quantity=Picture.count(查询,参数);
}
@凌驾
公共无效设置限制(整数限制){
这个极限=极限;
}
@凌驾
公共图片页面(整型页面){
如果(第==null页)
page=1;
列表图片=query.fetch(页面,限制);
返回新图片页面(图片、数量、页面、限制);
}
}
公共抽象类页面{
受保护的图片列表;
长期保护量;
受保护的整数页;
保护整数极限;
公开名单(){
返回图片;
}
公共长计数(){
退货数量;
}
公共布尔hasNext(){
退货(第*页限制>数量);
}
公共布尔值hasPrevious(){
返回(第!=1页);
}
公共布尔hasOtherPages(){
return(hasNext()| hasPrevious());
}
公共整数nextPageNumber(){
如果(!hasNext())
返回null;
返回(第+1页);
}
公共整数previousPageNumber(){
如果(!hasPrevious())
返回null;
申报表(第1页);
}
公共整数currentPageNumber(){
返回页面;
}
}
公共类PicturesPage扩展页面{
公共图片页面(列表图片、长数量、整型页面、整型限制){
这个。图片=图片;
这个。数量=数量;
this.page=page;
这个极限=极限;
}
}
我想去掉那些PicturesPaginator
和PicturesPage
并使其通用,但是抽象类页面中的list()
方法将返回一个通用列表(list
或list
,因为我在这里使用Play)。
我所期望的是这个list()
方法返回正确的列表,在我的例子中称为list
。这可能吗
注意:我现在有一个分页模块!框架,我的问题主要是为了进一步了解java:)
非常感谢你的帮助,我真的很感激
我希望这个list()方法返回正确的list,
在我的情况下,也就是列表。这可能吗
这不仅仅是可能的,如果你正确使用泛型,你会自动得到它。如果你申报
public class Page<T extends GenericModel>{
protected List<T> items;
public List<T> list() {
return items;
}
}
公共类页面{
受保护的清单项目;
公开名单(){
退货项目;
}
}
然后像这样使用它:
page = new Page<Picture>();
this.query = Picture.find(query, params);
Class<T> clazz;
public Paginator (Class<T> clazz) {
this.clazz = clazz;
//note that you need to handle exceptions, I'll leave them out for brevity
Method findMethod = clazz.getMethod("find", String.class, Array.class );
this.query = findMethod.invoke(null, query, params);
}
page=新页面();
然后
page.list()
实际上将返回一个list
,因为T
是一个类型参数,当声明page
时,它将被一个具体类型所取代。如果我理解正确,以下内容可能会有所帮助:
使配速通用。转向
public abstract class Page {
protected List<Picture> pictures;
public List<Picture> list() {
return pictures;
}
公共抽象类页面{
受保护的图片列表;
公开名单(){
返回图片;
}
致:
公共抽象类页面{
受保护的列表元素;
公开名单(){
返回元素;
}
然后将PicturesPage混凝土制成:
public class PicturesPage extends Page<Picture> {
公共类图片页面扩展页面{
我不确定这是否是您需要的,但您可以将Page类转换为:
public abstract class Page<T> {
protected List<T> pictures;
protected Long quantity;
protected Integer page;
protected Integer limit;
public List<T> list() {
return pictures;
}
public Long count() {
return quantity;
}
public boolean hasNext() {
return (page * limit > quantity);
}
public boolean hasPrevious() {
return (page != 1);
}
public boolean hasOtherPages() {
return (hasNext() || hasPrevious());
}
public Integer nextPageNumber() {
if (!hasNext())
return null;
return (page + 1);
}
public Integer previousPageNumber() {
if (!hasPrevious())
return null;
return (page - 1);
}
public Integer currentPageNumber() {
return page;
}
公共抽象类页面{
受保护的图片列表;
长期保护量;
受保护的整数页;
保护整数极限;
公开名单(){
返回图片;
}
公共长计数(){
退货数量;
}
公共布尔hasNext(){
退货(第*页限制>数量);
}
公共布尔值hasPrevious(){
返回(第!=1页);
}
公共布尔hasOtherPages(){
return(hasNext()| hasPrevious());
}
公共整数nextPageNumber(){
如果(!hasNext())
返回null;
返回(第+1页);
}
公共整数previousPageNumber(){
如果(!hasPrevious())
返回null;
申报表(第1页);
}
公共整数currentPageNumber(){
返回页面;
}
如果我理解正确,您引入泛型的问题如下:
page = new Page<Picture>();
this.query = Picture.find(query, params);
Class<T> clazz;
public Paginator (Class<T> clazz) {
this.clazz = clazz;
//note that you need to handle exceptions, I'll leave them out for brevity
Method findMethod = clazz.getMethod("find", String.class, Array.class );
this.query = findMethod.invoke(null, query, params);
}
AFAIK您不能直接调用泛型类型上的静态方法,因此您必须在此处使用反射。在这种情况下,您可能必须将参数类型的类作为参数传递(或从反射数据获取,如果存在),找到要调用的方法并调用它
是这样的:
page = new Page<Picture>();
this.query = Picture.find(query, params);
Class<T> clazz;
public Paginator (Class<T> clazz) {
this.clazz = clazz;
//note that you need to handle exceptions, I'll leave them out for brevity
Method findMethod = clazz.getMethod("find", String.class, Array.class );
this.query = findMethod.invoke(null, query, params);
}
您可以查看我的Play--Pagination模块的源代码,以了解我如何处理这类事情
您要做的是使页面也成为通用的,可能是非抽象的:
public class Page<T> {
public List<T> list() {}
}
公共类页面{
公共列表(){}
}
您可以不使用PicturesPage,只需执行以下操作:
new Page<Picture>()
newpage()
Paginator接口也需要进行泛化:
public interface Paginator {
public Page<T> page(Integer page);
}
公共接口分页器{
公共页面(整型页面);
}
泛化PicturesPaginator会更加困难,因为您调用Picture类上的方法。Java的泛型实现在运行时擦除类型,因此您必须处理类型标记和反射
public abstract class GenericPaginator<T> {
public GenericPaginator() {
Class<T> typeToken = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
// use reflection to invoke the finders methods
}
}
public class PicturesPaginator extends GenericPaginator<Picture> {}
公共抽象类GenericPaginator{
公共GenericPaginator(){
类别typeToken=(类别)(P