四.面向对象

解释说明

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

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

面向过程:执行者思维,对于简单问题,比如开车步骤 按照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
以上两个包虽然有逻辑的关系(文件件包含),但实际上是单独的两个个体

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值