怎样理解java中Function super V, ? extends T>这样的声明?
小白刚学java,有点C++基础,core java 10看到泛型这一章觉得和C++的泛型差别太过巨大,理解非常费劲,语法看着也及其别扭,JDK的有些API有些函数声明都看不懂。。。
比如Comparator里面的这个方法:
public static Comparator comparing(
Function<? super T, ? extends U> keyExtractor, Comparator<? super U> keyComparator)
怎么理解Function<? super T, ? extends U>这个声明呢,网上查了半天都在讲生产者消费者的的准则,
但好像和这个又对不上号,苦思冥想快2天了。。。求解
PS:还有为啥我觉得java的泛型系统像是个半成品,好多莫名其妙的限制啊!!??
再补充下,为什么参数是super返回值是extends
如果我们把函数想象成一个机器,比如面包机
参数是它需要的原料,比如白面粉
返回值是它能做的成品,比如面包
显然,对于原料我们需要提供的是白面粉或者它的派生类,比如一级白面粉、xx牌白面粉……但是如果是黑面粉,或者大米,这个面包机都不能工作。
而对于结果,恰恰相反,如果你要一个面包,这个机器能满足你,如果你要点心,也没有问题,任何基类都没有问题。但是如果你要切片面包或者法国面包,这个机器未必能满足你的要求了。
类似的,对于定义Lambda寒暑,我们需要让参数“严格”,用super,只能是派生类。对于返回值,我们需要让参数“宽松”,用extends,必须是基类。
通配符: “?”就是一个占位符,它不表示任何具体的类型,而是表示符合定义规则的一个或者多个类型的一个占位标志
边界:
<? extends T> 表示上界通配符 它表示T以及T的子类, 类型最高是T
<? super T> 表示下界通配符 它表示T以及T的超类,类型最高可到Object ,最低是T
<? extends T> 表示上界通配符 它表示T以及T的子类, 类型最高是T
设置泛型对象的上限使用extends,表示参数类型只能是该类型或该类型的子类:
声明对象:类名<?extends 类> 对象名
定义类:类名<泛型标签 extends 类>{}
设置泛型对象的下限使用super,表示参数类型只能是该类型或该类型的父类:
声明对象:类名<?super 类> 对象名称
定义类:类名<泛型标签 extends类>{}
这是java 8的lambda表达式,keyExtractor是相当于一个回调函数,它的参数是T,返回U,keyComparator是另一个回调函数。
从字面理解,第一个是提取需要比较的属性,第二个是比较。
lambda表达式参考:https://www.cnblogs.com/aoeiuv/p/5911692.html
java的泛型系统像是个半成品
这个是因为java是编译型语言,它必须在编译的程序的时候确定类型,所以它实际上用了“类型擦除”,也就是编译的时候将泛型类型替换成实际类型了。
这么做的好处是,编译器可以充分检查类型是否匹配,比如super,它可以判断这个类型是不是你要的派生类型。同时不用修改jvm的实现,直接就能运行,因为对于jvm,它根本就看不到泛型,看到的就是替换(或者说擦除)以后的类型。
坏处就是不能在运行的时候动态加载和创造泛型出来。
Function,这是函数式编程的核心内容。
这种泛型写法,我也见过,不过忘了啥意思,一般我还是可以推测的,T可以自己填写类型,比如String,T就代表了这个类型String,传入的继承必须这个类型,第一个难道是,传入的需要是泛型的父类?将你看的源码这里的方法贴出来,我研究研究,格式:包+类+方法名,我会自己去找