四.面向对象

    技术2022-07-11  127

    解释说明

    姓名职位动作张三程序员打卡,开会李四前台打卡,开会王五财务打卡,开会

    用表格表示一组数据,表结构理解为类,每一行数据对应一个对象; 姓名、职位相当于类中的属性; 动作早会相当于类中的方法;

    面向过程:执行者思维,对于简单问题,比如开车步骤 按照1234步骤完成即可,思考怎么用; 面向对象:设计者思维,对于复杂的事物,如造车,思考的是怎么设计,如何造车 Object-Oriented Analysis:面向对象分析 Object Oriented Programming:面向对象设计

    面向对象离不开面向过程,宏观上面向对象设计,微观上执行和处理数据仍然是面向过程;

    总结: 类可以看成一类对象的的模板,对象可以看成该类的一个具体实例。 类用于描述同一类型的对象的一个抽象概念,类中定义了这一类对象所具有的共同的属性、方法。

    package com.bhzt.base; import javax.lang.model.element.Name; public class ObjectOriented { //属性 public String name; public String title; //方法 public void work() { System.out.println(name+"的职位为"+title+",开始打卡"); System.out.println(name+"的职位为"+title+",开始开会"); } //构造方法 public ObjectOriented(){ } } package com.bhzt.test; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import com.bhzt.base.ObjectOriented; class ObjectOrientedTest { @BeforeEach void setUp() throws Exception { } @Test void ObjectOrented() { ObjectOriented objectoriented=new ObjectOriented(); objectoriented.name="zhangsan"; objectoriented.title="develop"; objectoriented.work(); } }

    package com.bhzt.base; import javax.lang.model.element.Name; public class ObjectOriented { //属性 public String name; public String title; private double x; private double y; /** * 无惨构造方法 * 1.通过new关键字调用 * 2.有返回值,但不能定义返回类型,不能在构造方法里return 返回值 * 3.如果没有定义构造方法,则编译器会自动定义一个无参的构造方法 * 4.方法名与类名相同 */ public ObjectOriented(){ } /** * 带参数构造方法 * @param name * @param title */ public ObjectOriented(String name,String title){ this.name=name; this.title=title; } public ObjectOriented(double x,double y) { this.x=x; this.y=y; } //方法 public void work() { System.out.println(name+"的职位为"+title+",开始打卡"); System.out.println(name+"的职位为"+title+",开始开会"); } /** * 计算距离 * @param ob * @return */ public double getDistance(ObjectOriented ob) { double _x=x-ob.x; double _y=y-ob.y; return Math.sqrt(_x*_x+_y*_y);//开平方 } } package com.bhzt.test; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import com.bhzt.base.ObjectOriented; class ObjectOrientedTest { @BeforeEach void setUp() throws Exception { } @Test void workTest() { ObjectOriented objectoriented=new ObjectOriented(); objectoriented.name="zhangsan"; objectoriented.title="develop"; objectoriented.work(); ObjectOriented objectoriented2=new ObjectOriented("lisi", "sale"); objectoriented2.work(); } @Test void getDistanceTest() { ObjectOriented o1=new ObjectOriented(3.0,4.0); ObjectOriented o2=new ObjectOriented(0,0); System.out.println(o1.getDistance(o2)); } }

    JVM

    内存分析

    从属于线程的区域

    JVM内存划分中,有部分区域是线程私有的。

    程序计数器:记录程序执行到了哪一步,当线程暂停在重新启动时,则从上次执行到的位置开始执行;每个线程都有自己的程序计数器。这是一个比较小的内存空间,存储当前线程正在执行的java方法的jvm指令地址,既字节码的行号。如果正在执行的是native方法,则这个计数器为空。

    虚拟机栈:每个线程在创建的时候都会创建一个虚拟机栈,生命周期与线程一致,线程退出时,线程的虚拟机栈也回收。虚拟机栈内保持一个个的栈帧,每次方法调用都会进行压栈,jvm对栈帧的操作只有出栈和压栈,方法调用结束时会进行出栈。该区域存储局部变量表,编译时期可知的各种基本类型数据、对象引用、方法出口等信息。

    本地方法栈:调用本地方法时使用的栈。

    堆 heap

    几乎所有创建的java对象实例,都是会直接分配到堆上。 堆被所有的线程所共享,在堆上的区域会被垃圾回收器做进一步的划分,如新生代,老年代。java虚拟机在启动的时候可以配置堆区域的大小。

    方法区

    所有线程共享,存储不变的数据;

    运行时常量池

    字符串常量,符号引用

    直接内存
    栈、堆特点

    虚拟机栈(简称:栈) 1.每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等) 2. JVM为每个线程创建一个栈,存放该线程执行方法的信息 3. 栈属于线程私有,不能实现线程间共享 4. 存储特性,先进后出 后进先出 5. 栈是由系统自动分配,速度快,是一个连续的内存空间

    堆: 1.用于存储创建好的对象和数组(数组也属于对象) 2.JVM只有一个堆,被所有线程共享 3.堆是一个不连续的内存空间,分配灵活 速度慢

    方法区: 实际也属于堆,只是用于存储类、常量相关信息

    package com.bhzt.base; public class Person { public String name; public int age; public void show() { System.out.println("姓名:"+name+",年龄:"+age); } } package com.bhzt.test; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import com.bhzt.base.Person; class PersonTest { @BeforeEach void setUp() throws Exception { } @Test void showTest()//step0 { Person p1=new Person();//step1 p1.name="张三";//step2 p1.age=20;//step3 p1.show();//step4 Person p2=new Person();//step5 p2.name="李四";//step6 p2.age=30;//step7 p2.show();//step8 } }

    垃圾回收机制

    Garbage Collection 由GC线程自动回收垃圾,主要回收堆里的垃圾,没有任何变量引用的对象被GC通过算法进行回收

    GC算法:

    1.引用计数器 当引用数为0时,则视为可回收 优点:算法简单 缺点:循环引用的无用对象 无法识别

    package com.bhzt.base; public class Person { public String name; public int age; Person p; public void show() { System.out.println("姓名:"+name+",年龄:"+age); } /** * 循环引用,GC引用计数器无法识别 */ public void test1() { Person p1=new Person(); Person p2=new Person(); p1.p=p2; p2.p=p1; p1=null; p2=null; } }

    2.引用可达法

    分代垃圾回收机制

    1.年轻代 Eden、Survivor 所有新生成的对象放到Eden区,由Minor GC清理生命周期短的对象。 Eden区满了,触发一次Minor GC。清理无用对象,将有用对象复制到Survivor1,Survivor2区中,仍然有用的对象循环存放到s1 or s2,当Minor GC对同一对象清理次数达到15次 仍有效则放到Tenured区。

    2.年老代 Tenured/Old 空间 在年轻代中经历了N(默认15)次垃圾回收仍然存活的对象,就会被放到年老代中。当年老代对象越来越多时,就需要启动Major GC和Full GC(全量回收)

    Major GC:清理Tenured代空间。 Full GC:清理年轻代和年老代。

    3.永久代 存放静态文件,如java类、方法等。

    JVM调优

    对FULL GC的调节,如下情况会导致FULL GC: 1.年老代被写满 2.永久代被写满 3.System.gc()被显示调用,该方法只是建议JVM清理,不是直接调用FULL GC(),程序员无权调用垃圾回收器,finalize是java提供给程序员用来释放对象或资源的方法,但尽量少用 4.上次GC后,Heap的各域分配策略动态变化

    总结

    1.创建大量无用对象 比如,for循环拼接字符串,使用了String 而不是StringBuilder,String是对象

    String str=""; for(int i=0;i<=100;i++) { str += i; //产生了100个String对象 }

    2.静态集合类的使用 像HashMap、Vector、List等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象也不被释放。

    3.各种连接对象未关闭 IO流对象、数据库连接对象、网络连接对象等属于物理连接,和硬盘或者网络连接,不使用的时候一定要关闭

    4.监听器的使用 释放对象时,没有删除相应的监听器

    this static关键字

    this:创建好的对象的地址 创建一个对象分4步: 1.分配对象空间,并将对象成员变量初始化 2.执行属性值的显示初始化 3.执行构造方法 4.返回对象的地址给相关的变量

    this不能放在static方法里

    static:用此声明的成员变量为静态变量,也称类变量。类变量的生命周期与类相同。

    package com.bhzt.base; public class PersonTow { public String a; public static String b;//静态变量,存储在方法区 public void getA() { System.out.println(a); System.out.println(b); } /** * 静态变量存储在方法区 */ public static void getB() { //System.out.println(a);//不能调用对象属性,只能调用方法区属性 //this.a //this指的是创建好的对象地址,静态区方法不能直接调用对象里的变量,需要先创建对象 System.out.println(b); } } @Test void getA() { PersonTow pt=new PersonTow(); pt.a="aaa"; pt.getA(); } /** * 做类的静态初始化 */ static { b="bbb"; }

    包机制

    包起名采用域名倒着写,如com.taobao. com.taobao.test 以上两个包虽然有逻辑的关系(文件件包含),但实际上是单独的两个个体

    Processed: 0.013, SQL: 9