#博客迁移#
“生有尽,业无穷”,第一次听说这句话时受到了强烈的震撼,那是在学校时管理学老师说的。
一、一个JVM指令
我不喜欢模糊的立场,却又怀疑过分肯定的答案——许知远
以前有个同事问我一个问题,他写了下面的代码
Parent parent=son;
parentMapper.insert(parent);
这段代码在执行的时候报错,提示不能把Son类型的插入到Parent表里,他很纳闷,都把son向上转型成Parent类型了,为什么还提示是Son类型呢?
我以前也遇到过这种坑,所以就直接告诉他说向上转型并不能改变对象的真实类型。为什么是这样的呢?当时事情都做完了,就想从字节码的层面找找原因。当时写了代码,然后执行javac、javap(查看代码及字节码),发现向上/向下转型那行代码的JVM指令都是invokespecial,这个指令表示调用初始化方法,但是向上转型调的是子类的初始化方法,就是向上转型后新的对象还是子类类型。向下转型调的是原始对象的类型的初始化方法。就是说不管是向上还是向下转型,新对象的类型和原始对象的类型还是一致的。
接着问题来了,invokespecial是怎么实现?Java的原理和Java代码的实现可以说是JVM的执行引擎来完成的,但是JVM执行引擎的原理和实现是用什么来做的呢?
这时想起了老师说的“生有尽,业无穷”。
二、死胡同与另一扇门
走进死胡同是令人沮丧的;打开新的一扇门是令人欣喜的。——我
很多技术都是以另一个或多个技术作为基础的。在一个领域里面穷根究底后总会遇到类似1+1=2的基础。遇到1+1就走进了死胡同,只有换个角度进入另一个领域才能打开新的一扇门。就比如Java基础是JVM,JVM基础是另一个领域一样。
但是进入一个领域到走进死胡同,再到进入另一个领域:
while(hasNextDoor()){
openTheDoor();
}
这样会被累死的,整个IT里有无数个小领域,生有尽,业无穷。奈何?
三、知识结构的广度与深度
这时就是知识结构的问题了,知识结构的广度和深度。深度和广度是互相作用的,没有广度很难往深度上发展,有了深度以后,自然就会有广度。
由于各种原因,本人的知识广度是相当广的,并且自信比多我3年工作经验的人的广度还要广,和多我5年工作经验的人差不多。可以说是很NB的全栈工程师了。要在这些方面都深入发展是不可能的。
四、兼顾广度与深度:自我定位
磨刀不误砍柴工,但是如果拿刀砍白菜,谁磨刀谁是傻子。——知乎用户
怎么兼顾知识结构的广度与深度呢?
我觉得这要看个人的自我定位了。给自己的定位不同涉及到的知识广度和深度就自然不同。难就难在自我定位上。
Java代码:
public void upConvert() {
Son son=new Son();
Parent upConvert=son;
}
public void downConvert1() {
Parent parent=new Parent();
Son downConvert=(Son) parent;
}
public void downConvert2() {
Parent sonInParent=new Son();
Son downConvert=(Son) sonInParent;
}
字节码:
public void upConvert();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: new #4 // class com/yuanye/Son
3: dup
4: invokespecial #5 // Method com/yuanye/Son."<init>":()V
7: astore_1
8: aload_1
9: astore_2
10: return
LineNumberTable:
line 22: 0
line 23: 8
line 24: 10
public void downConvert1();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: new #2 // class com/yuanye/Parent
3: dup
4: invokespecial #3 // Method com/yuanye/Parent."<init>":()V
7: astore_1
8: aload_1
9: checkcast #4 // class com/yuanye/Son
12: astore_2
13: return
LineNumberTable:
line 26: 0
line 27: 8
line 28: 13
public void downConvert2();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: new #4 // class com/yuanye/Son
3: dup
4: invokespecial #5 // Method com/yuanye/Son."<init>":()V
7: astore_1
8: aload_1
9: checkcast #4 // class com/yuanye/Son
12: astore_2
13: return
LineNumberTable:
line 30: 0
line 31: 8
line 32: 13
}
版权声明:本文归作者所有,如需转载,请保留原文链接,如有侵权,请在评论区留言联系管理员删除,管理员收到后会24小时内反馈(软件定制开发、广告合作、版权等其他事宜也可关注本站微信公众号“元页斋”,发送消息说明情况,管理员会尽快与您联系)