一、面向过程和面向对象
面向对象和面向过程都是对软件分析、设计和开发的一种思想,它指导着人们以不同的方式去分析、设计和开发软件。
1、面相过程:思考问题的方式是“按步骤实现”,接下来将步骤对应成方法,一步一步,最终完成。
这个适合简单任务,不需要过多的协作情况下。
2、面向对象:思想更契合人的思维模式。思考的是“怎么设计”。
3、面相对象和面相过程的总结
(1)都是解决问题的思维方式,都是代码组织的方式。
(2)解决简单问题可以使用面相过程。
(3)解决复杂问题:宏观上使用面向对象把握,微观上使用面向过程处理(方法)。
二、对象和数据管理(数据管理和企业管理的共同之处)
1、事务的发展总是遵循“量变引起质变”的哲学原则;企业管理和数据管理,甚至社会管理都有很多共通之处。
2、数据管理进程
(1)数据无管理时代
(2)数组管理和企业部门制
(3)对象和企业项目制
三、对象和类的关系
类可以看做是一个模板,或者图纸,系统根据类的定义来造出对象。
1、类:class
2、对象:object,instance(实例对象)
描述:类是对象抽象(特征、相似)的集合。程序运行,通过类产生无数个对象。
四、第一个类的定义
1、简单学生类编写
public class SxtStu {
//属性(成员变量)
int id;
String sname;
int age;
//方法
void study(){
System.out.println("我正在学习!");
}
//构造方法
SxtStu(){
}
}
2、属性(field,或者叫成员变量)
(1)用于定义该类或该类对象包含的数据或者静态特征。作用范围是整个类体。
(2)定义成员变量时,可以对其初始化。如果不初始化,java使用默认值对其初始化。
3、方法
(1)方法用于定义该类或该类实例的行为特征和功能实现。
(2)方法是类和对象实例行为特征的抽象。类似于面向过程中的函数。
(3)面向过程中,函数是最基本单位,整个程序由一个个函数调用组成。
(4)面向对象中,整个程序的基本单位是类,方法是从属于类和对象的。
[修饰符] 方法返回值类型 方法名(形参列表) {
// n条语句
}
4、main方法程序执行的入口
五、一个典型类的写法和调用,以及UML图
1、new 就是创建一个对象,相当于调用的某个类的构造方法,无阐述的构造方法可以由系统默认创建。方法名必须和类名保持一致,包括大小写一样。
2、类和类之间是可以互相引用的,互相嵌套。
3、UML图:表示类的基本结构
六、面向对象内存分析
1、java虚拟机的内存可以分为三个区域:栈stack、堆heap、方法区method area。(语言的底层基本类似)
2、栈的特点如下:
(1)栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)。
(2)JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)。
(3)栈属于线程私有,不能实现线程间的共享。
(4)栈的存储特性是“先进后出,后进先出”。
(5)栈是由系统自动分配,速度快!栈是一个连续的内存空间。
3、堆的特点如下:
(1)堆用于存储创建好的对象和数组(数组也是对象)。
(2)JVM只有一个堆,被所有线程共享。
(3)堆是一个不连续的内存空间,分配灵活,速度慢!
4、方法区(又叫静态区)特点如下:
(1)JVM只有一个方法区,被所有线程共享!
(2)方法区实际也是堆,只是用于存储类、常量相关的信息!
(3)用来存放程序中永远是不变或唯一的内容(类信息【class对象】、静态变量、字符串常量等)。
七、构造器
1、构造器也叫构造方法(constructor),用于对象的初始化。(方法的特性全部是用于构造器里面)
2、要点:
(1)通过new关键字调用。
(2)构造器虽然有返回值,但是不能定义返回值类型(返回的类型肯定是本类),不能在构造器里面使用return返回某个值。
(3)如果我们没有定义构造器,则编译器会自动定义一个无参的构造函数。如果已定义,编译器则不会自动添加!
(4)构造器的方法名必须和类名一致。
八、构造方法的重载:和方法的重载一模一样
1、方法名称相同,形参列表不同。
2、就近原则。
3、this表示创建的成员变量。
4、构造方法的第一句总是super();
九、垃圾回收机制(garbage collection)和垃圾回收原理和算法
1、java引入了垃圾回收机制,而C++没有。
2、内存管理
(1)java的内存管理很大程度指的就是对象的管理,其中包括对象空间的分配和释放。
(2)对象空间的分配:使用new关键字创建对象即可。
(3)对象空间的释放:将对象赋值null即可。垃圾回收器将负责回收所有“不可达”对象的内存空间。
3、垃圾回收过程
任何垃圾回收算法一般要做两件事情:
(1)发现无用的对象。
(2)回收无用对象占用的内存空间。
(3)垃圾回收机制保证可以将“无用的对象”进行回收。即发现后清除并整理。
(4)无用对象指的是没有任何变量引用该对象。
4、垃圾回收相关算法
(1)引用计数法:堆中的每个对象都有一个引用计数。被引用加1,被引用值为null,减1,直到为0成为无用对象。
优点:算法简单。
缺点:“循环引用的无用对象”无法识别。
(2)引用可达法(根搜索算法):程序把所有的引用关系看成一张图,从一个节点GC root开始,寻找对应的引用节点,找到之后继续往下寻找,当所有节点寻找完毕后,剩下没有被引用的节点成为无用节点。
5、通用的分代垃圾回收机制:不同的对象声明周期不一样。不同生命周期的对象采用不同的回收算法,提高回收效率。
(1)对象分为三种状态:年轻代、年老代、持久代。
(2)JVM将堆内存划分为Eden(年轻代)、survivor和tenured/old空间。
①年轻代:所有新生成的对象放在Eden。目标是尽快收集生命周期短的对象,对应的是minor GC,算法采用效率较高的复制算法。频繁操作,浪费内存空间。当Eden区域放满对象,就会将对象放到old区域。
②年老代:在年轻代经历了N(默认15)次垃圾回收后依然存活的对象,会被放到年老代中。可以看做年老代存放生命周期较长的对象。年老代对象放满,就需要启动major GC 和full GC(全量回收),全面清理年轻代区域和年老代区域。
③持久代:用于存放静态文件,如java类、方法等。持久代对垃圾回收没有显著的影响。
(3)minor GC:年轻代满了触发一次,将有用对象复制到survivor1和survivor2中(这两个区空间大小相同,同一时间,一个为空,一个在使用)。
(4)major GC:清理老年代区域。
(5)full GC:全面清除,会对系统产生影响。
6、垃圾回收过程(建议可以口述)
(1)新创建的对象绝大多数存在Eden中。
(2)当Eden满了(达到一定比例),不能创建新对象,则触发垃圾回收(GC),将无用对象清理掉,然后剩余对象复制到某个survivor中,如s1同时清空Eden区域。
(3)当Eden区域再次满了,会将s1中不能清空的对象存到另外一个survivor中,如s2,同时将Eden中不能清空的对象,也复制到s1中,保证s1和Eden都被清空。
(4)重复多次(默认15次)survivor中没有被清理的对象,会被复制到老年代old中。
(5)当old区域满了,则会触发一个一次完整的垃圾回收(fullGC)之前新生代的垃圾回收成为minor GC。
7、JVM调优和fullGC
在对JVM调优的过程中,很大一部分工作就是对于Full GC的调节。有如下原因可能导致Full GC:
(1).年老代(Tenured)被写满
(2).持久代(Perm)被写满
(3).System.gc()被显式调用(程序建议GC启动,不是调用GC)
(4).上一次GC之后Heap的各域分配策略动态变化
8、开发中容易造成内存泄露的操作【暂时了解回头细看】
(1)创建大量无用对象:在需要大量拼接字符串时,使用的是String而不是StringBuilder。
(2)静态集合类的使用:如HashMap、Voctor、List等的使用。这些静态变量的生命周期和应用程序是一样的,所有的对象object也不能被释放。
(3)各种连接对象(IO流对象,数据库连接对象、网络连接对象)未关闭。这些对象属于物理连接,和硬盘或者网络连接,不使用的时候一定要关闭。
(4)监听器的使用:释放对象时,没有删除相应的监听器。
9、重点:
(1)程序员无权调用垃圾回收器。
(2)程序员可以调用system.gc(),该方法只是通知JVM,并不是运行垃圾回收器。尽量少用,会生成full Gc,成本高,影响系统性能。
(3)fanilze方法,是java提供给程序员用来释放对象或者资源的方法,尽量少用。
十、对象创建的过程和this的本质
1、创建一个对象分为如下四个步骤
(1)分配对象空间,并将对象成员变量初始化为0或空。
(2)执行属性值的显式初始化。
(3)执行构造方法。
(4)返回对象的地址给相关的变量。
2、this的本质就是“创建好的对象的地址”!由于在构造方法调用前对象已经创建。因此,在构造方法中也可以使用this来代表“当前对象”。
3、this最常用的用法:
(1)在程序产生二义性之处,应使用this来指明当前对象;普通方法中,this总是指向调用该方法的对象。构造方法中,this总是正要初始化的对象。
(2)使用this关键字调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句。
3、this不能用于static方法中。
十一、static关键字
1、在类中,用static声明的成员变量为静态成员变量,也称为类变量。类变量的生命周期和类相同,在整个应用程序执行期间都有效。
特点如下:
(1)为该类的公用变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化。
(2)对该类的所有对象来说,static成员变量只有一份。被该类的所有成员变量共享。
(3)一般用“类名.类属性/方法”来调用,也可以通过对象引用和类名(不需要实例化)来访问静态成员。
(4)在static方法中不可直接访问非static的成员。
2、核心要点:static修饰的成员变量和方法,从属于类,普通变量和方法从属于对象。
3、静态方法只能调用静态方法。
4、静态初始化块
(1)、构造方法用于对象的初始化。静态初始化块用于,类的初始化操作!在静态初始化块中不能直接访问非static成员。
(2)、注意事项:
静态初始化块执行顺序(学习完继承再看这里):
①上溯到object类,先执行object的静态初始化块,知道初始化到我们的类的静态初始化块为止。
②构造方法执行顺序和上面顺序一样。
十二、参数的传值机制
1、java中,所有参数传递都是“值传递”,也就是传递的是“值的副本”。类似于我们得到的是“原参数的复印件,而不是原件”,复印件改变不会影响到原件。
2、基本数据类型参数的传值:传递的是值的副本。副本改变不会影响原件。
3、引用类型参数的传值:传递的是值的副本。但是引用类型指的是“对象的地址”。因此副本和原参数都指向了同一个地址,改变副本指向地址对象的值,也就意味着原参数对象的值要发生了改变。
十三、java包
1、包机制:是java管理类的重要手段。开发中我们会遇到大量同名的类,通过包我们很容易解决类重名的问题,也可以实现对类的有效管理。包对于类,相当于文件夹对文件的作用。
2、package要点
(1)通常是类的第一句非注释性语句。
(2)包名:域名倒着写即可,再加厚是那个模块名,便于管理类。
3、注意事项
(1)写项目时,都要加包,不要使用默认包。
(2)com.gao和com.gao.car,这两个包没有包含关系,是两个完全独立的包。只是逻辑上看起来后者是前者的一部分。
4、jdk中主要的包
5、导入import
要是用其他包里面的类,就要使用import导入,在本类中就可以直接用类名使用。否则就要写出完整的包名和类名。
(1)注意要点
①java会默认导入java.lang包下所有的类,因此这些类我们可以直接使用。
②如果倒入两个同名的类,只能用包名+类名来显示调用相关类。
③import java.util.*;//导入该包下所有的类。会降低编译速度,但不会降低运行速度。
6、静态导入:是jdk1.5新增的功能,其作用是用于导入指定类的静态属性。这样我们就可以直接使用静态属性。
import static java.lang.Math.*;//导入Math类的所有静态属性
import static java.lang.Math.PI;//导入Math类的PI属性