关于java泛型的问题,? extends Object

疯狂小芋头 2016-01-13 02:33:32
情况是这样的:
在不确定数据的类型的情况下,我需要将数据引用保存下来使用,如果使用以下方式:
public void setMethod(List<Object> data);

是没有问题,也可以保存下所有类型的数据,但是前提是在传入参数之前就需要将数据强制转换成object并创建新的List<Object>,才能将数据作为参数传入;

如果不创建List<Object>的话可以直接这么做:
public void setMethod(List<? extends Object> data);

这样不管List<>中的数据类型是什么都可以直接赋值而不需要将对象全部转成Object再传参;

但是问题在于返回该对象时,如果我传入的类型是List<A>,A必然是extends自Object的,这时候返回传入的参数时,
public List<? extends Object> getMethod();

返回的类型必须是?extends Object,否则会编译出错提示类型不正确;

我想请问有什么办法是可以在使用List<? extends Object>传参之后,返回该类型时是一个确定的类型,比如直接返回List<A>类型或者List<Object>类型么?(返回List<Object>也是可以的,这个我自己试过,但是前提是需要将List<? extends Object>中的数据全部添加到新创建的List<Object>之后再可以返回,在不这么干的情况下有其它办法直接返回确定类型的数据么?)

如果没有其它的办法可以处理这个问题,那么感觉这样子就不如处理数据时使用List<T> 数据吧?这样的话至少返回的数据是类型是确定和统一的(当然前提是使用的数据类型都是一样的,不会一个list里同时需要多种类型的数据)

以下是例子:
public class A{
//此处只能定义类型是?extends Object,否则不能直接赋值,只能进行二次拷贝
private List<? extends Object> mData;
public A(List<? extends Object> data){
mData=data;
}

//此处只能返回类型是?extends Object,不能直接返回Object或者对应的那个?类型,否则编译出错
public List<? extends Object> getData(){
//List<Object> objs=new ArrayLIst<Object>();
//for(Object o:mData){
// objs.add(o);
//}
//reutrn objs;这种情况下才可以正常返回List<Object>
return mData;
}
}


如果知道的麻烦请教一下,提前谢谢!
...全文
325 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
疯狂小芋头 2016-01-27
  • 打赏
  • 举报
回复
引用 4 楼 windowsoahil 的回复:
? extends A承诺这是一个A或A的子类类型,而? super A承诺这是一个A或A的父类类型 这两种情况是对立的,就是说如果你往一个容器里装了一个? extends A类型,那实际上你只能拿出一个? super A类型。从逻辑上很容易理解,想想就能明白。 所以上述需求不用反射是做不到的。关于通配符,记不住的时候可以参考jdk中Collections类的copy方法,就能理解通配符想表达的本意了。 static <T> void copy(List<? super T> dest, List<? extends T> src)
并不是通配符的使用方法不明确,虽然确实是很容易搞乱,但这一部分基本还没有到把extends和super的作用混乱的作用。我主要是想寻问是否有我上面提到的过的在输入提供最大的兼容性类型数据时,输出时可以确定的输出原始的输入类型的方法没有。 确实这个可能比较不好搞,如果直接处理感觉还是不现实的,不过你提到的反射是一种解决方案。目前使用的并不是一定需要这种解决方案,我只是在做这个的时候想到是否能做到这种可能所以特地过来问一下。之前也有寻找过类型的解决方案和替代方法,但对于输入类型通配但输出还原类型这部分并没有查找到,所以也是好奇是否有什么其它的解决方案。 谢谢热心的回答,这个问题就在这里结贴了~~
疯狂小芋头 2016-01-27
  • 打赏
  • 举报
回复
引用 3 楼 u011696233 的回复:
你要是做接口给别人用..就最好自己固定一个类..不容别人随便传什么都可以进来..不管里面有没有数据..里面也不确定有哪些方法..那这个接口用处到底体现在什么地方?
其实存在一个问题是,如果只是针对一个对象那是好办的。事实上也是定义了一个父类级的抽象对象AbsClazz,如果处理的单个对象的话全都是以父类抽象对象来处理的,这个没有问题。 但是问题在于某些地方是需要的是批量的数据,所以原始的的数据类型将是这样的:List<Clazz>,而父类对象的数据将是这样的:List<AbsClazz>,在这种情况下其实两个数据类型是不一统一的,所以在输入数据时,要不得将子类全部再转成父类的List<AbsClazz>,要不需要接口接收的参数类型是List<Clazz>,定义List<? extends Object>是为了方便传入数据时不需要做二次的转换,目前数据只需要传入,基本不需要返回输出,所以这个接口是有效的。 只是我做这个的时候想到如果需要数据输出时,是否可以直接返回一个原始的数据类型,即输入类型=输入类型,这样的话那输出时不需要二次转换类型了。当然如果统一只用父类型肯定也不需要,但同样的,在输出时可能子类有自己特有的方法,所以这时是输出后还是很可能需要二次转换类型。 由于? extends Object 的兼容性很高,所以特别想知道是否有可能返回时也可以返回一个具体有效的类型而不是又是一批被通配了的数据类型;之前其实已经查过并考虑过多个解决方案或者替换方案,但对以上所提到的还没有看到有类似的解决方案,所以特来问一下。 看情况应该是没办法直接这么做了,那也不强求;当然你说的我觉得还是很有道理,现在想想对外的接口应该是类型统一起来会比一个通配类型或者不确定类型更强,维护起来也会更方便。谢谢~
解开者 2016-01-13
  • 打赏
  • 举报
回复
? extends A承诺这是一个A或A的子类类型,而? super A承诺这是一个A或A的父类类型 这两种情况是对立的,就是说如果你往一个容器里装了一个? extends A类型,那实际上你只能拿出一个? super A类型。从逻辑上很容易理解,想想就能明白。 所以上述需求不用反射是做不到的。关于通配符,记不住的时候可以参考jdk中Collections类的copy方法,就能理解通配符想表达的本意了。 static <T> void copy(List<? super T> dest, List<? extends T> src)
独自漫步 2016-01-13
  • 打赏
  • 举报
回复
你要是做接口给别人用..就最好自己固定一个类..不容别人随便传什么都可以进来..不管里面有没有数据..里面也不确定有哪些方法..那这个接口用处到底体现在什么地方?
疯狂小芋头 2016-01-13
  • 打赏
  • 举报
回复
引用 1 楼 u011696233 的回复:
定义一个泛型类...
class Pair<T> {  
    private T value;  
        public Pair(T value) {  
                this.value=value;  
        }  
        public T getValue() {  
        return value;  
    }  
    public void setValue(T value) {  
        this.value = value;  
    }  
}  
...........
public static void main(String[] args) throws ClassNotFoundException {  
        Pair<String> pair=new Pair<String>("Hello");  
        String str=pair.getValue();  
        System.out.println(str);  
        pair.setValue("World");  
        str=pair.getValue();  
        System.out.println(str);  
    }  
这个也知道是可以的,主要其实想解决的是,我把接口给别人用,我并不知道对方可能用上什么类型的数据,所以才想使用? extends Object来处理,这样可以保存原有的引用,同时也不需要对数据进行转存,所以就想知道返回的时候可以直接返回Object类型么。另外,刚才确定了,可以直接返回?类型,但这个是任意类型都可以,我觉得也有点不妥。 理想的情况是:不管对方需要的数据类型是什么,接口都可以直接将数据传入,而取出的时候也是原来的类型,这是最好的。如果实在不行那肯定也没办法。 类似上面的情况,如果对方取出数据时,需要重新定义一个List<? extends Object>的类型才能取到数据,我觉得有点麻烦,是吧?
独自漫步 2016-01-13
  • 打赏
  • 举报
回复
定义一个泛型类...
class Pair<T> {  
    private T value;  
        public Pair(T value) {  
                this.value=value;  
        }  
        public T getValue() {  
        return value;  
    }  
    public void setValue(T value) {  
        this.value = value;  
    }  
}  
...........
public static void main(String[] args) throws ClassNotFoundException {  
        Pair<String> pair=new Pair<String>("Hello");  
        String str=pair.getValue();  
        System.out.println(str);  
        pair.setValue("World");  
        str=pair.getValue();  
        System.out.println(str);  
    }  

50,523

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧