为了账号安全,请及时绑定邮箱和手机立即绑定
慕课专栏

目录

索引目录

Java小白踩坑录

原价 ¥ 29.90

立即订阅
故事三:偷天换日--产品经理的变态需求
更新时间:2020-01-06 08:34:03
不想当将军的士兵,不是好士兵。

——拿破仑

本故事纯属虚构,如有雷同,纯属巧合。

故事背景

一大早,产品经理小 P 就兴冲冲地跑到小白的座位旁边。

小 P:” 小白兄弟,首先恭喜你获得这个月的公司月度之星呀!我这边有个需求,需要你帮忙支援一下,我已经跟你们领导小 L 打好招呼了,他也同意你暂时调到新项目中支持,这个项目已经和外部谈得差不多了,项目完成后有项目奖金和 outing 团建哦。“

小白:” 既然领导都同意了,我肯定支持,很高兴一起合作!“

小 P:” 现在对方根据我们提供的文档,提出了一个要求,需要我们这边的接口修改后,就可以和对方联调,然后上线了,只差最后一脚了,你一定要帮忙。“

小白:” 能否将需求给我详细解释一下?“

小 P:” 是这样的,之前我们有个接口,是返回用户的各项评分,这个接口已经上线半年了,但客户要求我们不但要返回用户的各项评分,还要将描述一下分数的意义。“

小 P:” 原来接口是这样的 List<Integer> getScoresByUser(UserInfo uinfo),返回 60、1500、90 这样的得分,现在该接口要返回 60,活跃度中等【0~100】、1500、粉丝数、90,好评度【0-100】“。

小白:” 不是可以新加一个接口给对方吗?“

小 P:” 不可以,双方已经达成统一了,大老板也拍板了,没法修改,今天开发,明天联调上线。“

小白:“天雷滚滚,伤我心!”

img
图片来自于网络,版权为原作者所有
旁白:

产品经理口头禅:

这个需求很简单,怎么实现我不管。

哪种语言你随便,不服可以找老板。

横批:明天上线。

寻找解决方案

沟通完成后,小白拖着郁闷的身心,拉下新项目的代码,想着解决方案。先整理思路:

原先的接口原型:

	public static void main(String[] args) {
		 ArrayList<Integer> list = new 	ArrayList<>();
		 	//todo ,get hot socore
		 	list.add(60); 
		 	
		 	//todo get fans
		 	list.add(1500);
		 	
		 	//todo get evaluation
		 	list.add(90);
		 	
		 	System.out.println(Arrays.toString(list.toArray()));
	}

打印出结果:

[60, 1500, 90]

新接口想要打印出:

[60,活跃度中等【0~100】,1500,粉丝数,90,好评度【0-100】]

小白一直想吼出,老子不干了!

img
图片来自于网络,版权为原作者所有

但想想现在还是菜鸟,忍忍忍。

小白想到,“对了,我解决不了,可以找扫地僧问问。他经验丰富,碰到过各种变态需求,应该有思路吧。”

考虑到下个月要不要流落街头的问题,小 B 赶紧找到扫地僧,说了产品经理小 P 的要求,问他有没有办法解决。

扫地僧:” 这个需求有点麻烦,一周的下午茶,我帮你解决,怎么样?“

小白:” 有点狠,但没有问题,知识无价嘛。“

看小白那么爽快,扫地僧放下手头的《代码大全 2》,扫了一眼代码,敲了一通键盘后,又拿起了《代码大全 2》看了起来。

扫地僧:“好了,你运行一下吧!”。

小白赶紧试了一下,果然可以了!

	public static void main(String[] args) {
    	ArrayList<Integer> list = new 	ArrayList<>();		 	
		 list.add(2);
		 list.add(3);
		 try {
		 //todo ,get hot socore
		 list.add(60); 
		 list.getClass().getMethod("add", Object.class).invoke(list, "活跃度中等【0~100】");
		 		 //todo get fans
		 list.add(1500);
		 list.getClass().getMethod("add", Object.class).invoke(list, "粉丝数,排名 3689 位");
		 	
		 //todo get evaluation
		 list.add(90);	
		 list.getClass().getMethod("add", Object.class).invoke(list, "用户评价,超越 92%的用户");
		 
		 } catch (Exception e) {
		 e.printStackTrace();
		 }
		 System.out.println(Arrays.toString(list.toArray()));
	}

怎么回事?

img
图片来自于网络,版权为原作者所有

小白暗想,一周的下午茶总得知道原因吧?不能白白浪费这个机会,于是继续缠着扫地僧问了起来,扫地僧被烦得无奈,遂慢慢给他讲解。原来因为种种原因,Java 不能实现真正的泛型,只能使用类型擦除来实现伪泛型。

类型擦除

当编译器对带有泛型的 Java 代码进行编译时,它会去执行类型检查和类型推断,然后生成普通的不带泛型的字节码,这种字节码可以被一般的 Java 虚拟机接收并执行,这种技术被称为擦除(erasure)。这样虽然不会有类型膨胀问题,但是也引起来许多新问题,所以,SUN 对这些问题做出了种种限制,避免我们发生各种错误。

编译器可以在对源程序(带有泛型的 Java 代码)进行编译时使用泛型类型信息保证类型安全,对大量如果没有泛型就不会去验证的类型安全约束进行验证,同时在生成的字节码当中,将这些类型信息清除掉。

追根究底

小白:“那您老是怎么知道的?类型擦除是在哪里规定的呢?”

扫地僧:“问到点子上了,JLS4.6 Type Erasure 有详细的介绍规定,你自己去看吧,不要烦我!”

参考资料:

【1】Java 解惑

}
立即订阅 ¥ 29.90

你正在阅读课程试读内容,订阅后解锁课程全部内容

千学不如一看,千看不如一练

手机
阅读

扫一扫 手机阅读

Java小白踩坑录
立即订阅 ¥ 29.90

举报

0/150
提交
取消