首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往
您找到你想要的搜索结果了吗?
是的
没有找到

《重构》第七章 - 读后感(类的重构要点)

上一章大概得学习了一下函数重构的手法,主要有9种。但是平心而论,有多少人还是随心所欲的写代码?所以我们做任何事情的时候还是得静下心来,把它当作一个艺术品去对待,才可能会有质的提升,而我们都提浮躁了。读完本书的第三章,我们可能都是飘飘然,似懂非懂。但是到了第六章之后就成了硬菜了。在读完之后,本人今天写代码突然发觉不知道如何写了,感觉代码中的问题很多,就第六章的函数提炼和函数内联以及变量内联。我们都没有做到,更别说返参和入参的复用了。感情整个代码都已经变成了垃圾,在写完一个方法之后,我感觉昨天的感悟修改了好几遍,才勉强觉得凑活。真心感慨以前怕是在假装写代码。确实越来越觉得读完这本书,会对一个开发人员思路和包结构设计都有很大的帮助。先不扯了,咋看一下本书的第七章:对象之间的搬移特性

01

【JVM我可以讲一个小时】

验证的第一步就是文件的格式验证,验证class文件里面的魔数和主次版本号,发现它是一个jvm可以支持的class文件并且它的主次版本号符合兼容性要求,所以验证通过。然后又回到了加载,它会将class文件这个二进制静态文件转化到方法区里面,转化为方法区的时候,会有一个结构的调整,将静态的存储文件转化为运行时数据区,这个转化等于说又回到了加载,这就是我说的第三步加载。接着到了方法区的运行时数据区以后,在java堆内存里面生成一个当前类的class对象,作为方法区里面这个类,被各种访问的一个入口。比如说object类,它是所有类都继承它,访问它,所以它也需要一个被各种类访问的入口。object类先加载,加载完成之后,它经过这一系列的操作,把自己java.lang.object放到这个堆里面,要让其他的类进行访问,这个是第四步的加载。第五步又跳到了连接里面验证,验证里面的第二步元数据验证,它会对字节码描述的信息进行语义分析,比如:这个类是不是有父类,是不是实现了父类的抽象方法,是不是重写了父类的final方法,是不是继承了被final修饰的类等等。第三步,字节码验证,通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的,比如:操作数栈的数据类型与指令代码序列是不是可以配合工作,方法中的类型转换是不是有效等等。第四步,符号引用验证:确保解析动作可以正确执行,比如说:通过符号引用是不是可以找到对应的类和方法,符号引用中类、属性、方法的访问性是不是能被当前类访问等,验证完成之后,需要做准备。也就是第六步,准备就是给类的静态变量分配内存,并赋予默认值。 我们的类里,可能会包含一些静态变量, 比如说public static final int a = 12; 得给a这个变量分配个默认值 0,再比如public static User user = new User(); 给 static的变量User分配内存,并赋默认值null。如果是final修饰的常量,就不需要给默认值了,直接赋值就可以了。然后就是解析,解析就是将符号引用变为直接引用,该阶段会把一些静态方法替换为指向数据储存在内存中的指针或者句柄,也就是所谓的直接引用,这个就是静态链接过程,是在初始化之前完成。有静态链接就有动态链接,动态链接是在程序运行期间完成将符号引用替换为直接引用,比如静态方法里面有个方法,在运行的时候,方法是存放在常量池中的符号,运行到这个符号,就是找这个符号对应的方法区,因为代码的指令是加载到方法区里面去的,最后把方法对应代码的地址放到栈帧中的动态链接里。后面就是第七步初始化了,初始化就是对类的静态变量初始化为指定的值并且会执行静态代码块。 比如准备阶段的public static final int a = 12;这个变量,就是准备阶段给static变量a赋了默认值0,这一步就该把12赋值给它了。还有static的User public static User user = new User(); 把User进行实例化。

02

【JVM我可以讲一个小时】

验证的第一步就是文件的格式验证,验证class文件里面的魔数和主次版本号,发现它是一个jvm可以支持的class文件并且它的主次版本号符合兼容性要求,所以验证通过。然后又回到了加载,它会将class文件这个二进制静态文件转化到方法区里面,转化为方法区的时候,会有一个结构的调整,将静态的存储文件转化为运行时数据区,这个转化等于说又回到了加载,这就是我说的第三步加载。接着到了方法区的运行时数据区以后,在java堆内存里面生成一个当前类的class对象,作为方法区里面这个类,被各种访问的一个入口。比如说object类,它是所有类都继承它,访问它,所以它也需要一个被各种类访问的入口。object类先加载,加载完成之后,它经过这一系列的操作,把自己java.lang.object放到这个堆里面,要让其他的类进行访问,这个是第四步的加载。第五步又跳到了连接里面验证,验证里面的第二步元数据验证,它会对字节码描述的信息进行语义分析,比如:这个类是不是有父类,是不是实现了父类的抽象方法,是不是重写了父类的final方法,是不是继承了被final修饰的类等等。第三步,字节码验证,通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的,比如:操作数栈的数据类型与指令代码序列是不是可以配合工作,方法中的类型转换是不是有效等等。第四步,符号引用验证:确保解析动作可以正确执行,比如说:通过符号引用是不是可以找到对应的类和方法,符号引用中类、属性、方法的访问性是不是能被当前类访问等,验证完成之后,需要做准备。也就是第六步,准备就是给类的静态变量分配内存,并赋予默认值。 我们的类里,可能会包含一些静态变量, 比如说public static final int a = 12; 得给a这个变量分配个默认值 0,再比如public static User user = new User(); 给 static的变量User分配内存,并赋默认值null。如果是final修饰的常量,就不需要给默认值了,直接赋值就可以了。然后就是解析,解析就是将符号引用变为直接引用,该阶段会把一些静态方法替换为指向数据储存在内存中的指针或者句柄,也就是所谓的直接引用,这个就是静态链接过程,是在初始化之前完成。有静态链接就有动态链接,动态链接是在程序运行期间完成将符号引用替换为直接引用,比如静态方法里面有个方法,在运行的时候,方法是存放在常量池中的符号,运行到这个符号,就是找这个符号对应的方法区,因为代码的指令是加载到方法区里面去的,最后把方法对应代码的地址放到栈帧中的动态链接里。后面就是第七步初始化了,初始化就是对类的静态变量初始化为指定的值并且会执行静态代码块。 比如准备阶段的public static final int a = 12;这个变量,就是准备阶段给static变量a赋了默认值0,这一步就该把12赋值给它了。还有static的User public static User user = new User(); 把User进行实例化。

05
领券