1700447395
编写高质量代码:改善Java程序的151个建议 建议98:建议采用的顺序是List<T>、List<?>、List<Object>
1700447396
1700447397
List<T>、List<?>、List<Object>这三者都可以容纳所有的对象,但使用的顺序应该是首选List<T>,次之List<?>,最后选择List<Object>,原因如下:
1700447398
1700447399
(1)List<T>是确定的某一个类型
1700447400
1700447401
List<T>表示的是List集合中的元素都为T类型,具体类型在运行期决定;List<?>表示的是任意类型,与List<T>类似,而List<Object>则表示List集合中的所有元素为Object类型,因为Object是所有类的父类,所以List<Object>也可以容纳所有的类类型,从这一字面意义上分析,List<T>更符合习惯:编码者知道它是某一个类型,只是在运行期才确定而已。
1700447402
1700447403
(2)List<T>可以进行读写操作
1700447404
1700447405
List<T>可以进行诸如add、remove等操作,因为它的类型是固定的T类型,在编码期不需要进行任何的转型操作。
1700447406
1700447407
List<?>是只读类型的,不能进行增加、修改操作,因为编译器不知道List中容纳的是什么类型的元素,也就无法校验类型是否安全了,而且List<?>读取出的元素都是Object类型的,需要主动转型,所以它经常用于泛型方法的返回值。注意,List<?>虽然无法增加、修改元素,但是却可以删除元素,比如执行remove、clear等方法,那是因为它的删除动作与泛型类型无关。
1700447408
1700447409
List<Object>也可以读写操作,但是它执行写入操作时需要向上转型(Up cast),在读取数据后需要向下转型(Downcast),而此时已经失去了泛型存在的意义了。
1700447410
1700447411
打个比方,有一个篮子用来容纳物品,List<T>的意思是说,“嘿,我这里有一个篮子,可以容纳固定类别的东西,比如西瓜、番茄等”。List<?>的意思是说“嘿,我也有一个篮子,我可以容纳任何东西,只要是你想得到的”。而List<Object>就更有意思了,它说“嘿,我也有一个篮子,我可以容纳所有物质,只要你认为是物质的东西就都可以容纳进来”。
1700447412
1700447413
推而广之,Dao<T>应该比Dao<?>、Dao<Object>更先采用,Desc<Person>则比Desc<?>、Desc<Object>更优先采用。
1700447414
1700447415
1700447416
1700447417
1700447419
编写高质量代码:改善Java程序的151个建议 建议99:严格限定泛型类型采用多重界限
1700447420
1700447421
从哲学上来说,很难描述一个具体的人,你可以描述它的长相、性格、工作等,但是人都是有多重身份的,估计只有使用多个And(与操作)将所有的描述串联起来才能描述一个完整的人,比如我,上班时我是一个职员,下班了坐公交车我是一个乘客,回家了我是父母的孩子,是儿子的父亲……角色时刻在变换。那如果我们要使用Java程序来对一类人进行管理,该如何做呢?比如在公交车费优惠系统中,对部分人员(如工资低于2500元的上班族并且是站立着的乘客)车费打8折,该如何实现呢?
1700447422
1700447423
注意这里的类型参数有两个限制条件:一为上班族;二为是乘客。具体到我们的程序中就应该是一个泛型参数具有两个上界(Upper Bound),首先定义两个接口及实现类,代码如下:
1700447424
1700447425
//职员
1700447426
1700447427
interface Staff{
1700447428
1700447429
//工资
1700447430
1700447431
public int getSalary();
1700447432
1700447433
}
1700447434
1700447435
//乘客
1700447436
1700447437
interface Passenger{
1700447438
1700447439
//是否是站立状态
1700447440
1700447441
public boolean isStanding();
1700447442
1700447443
}
[
上一页 ]
[ :1.700447394e+09 ]
[
下一页 ]