p 方法
- 方法声明格式:
java
[修饰符1 修饰符2 ...] 返回值类型 方法名(形式参数列表){
java语句;......;
}
- 方法调用方式
普通方法 | 对象.方法名(实参列表) |
---|---|
静态方法 | 类名.方法名(实参列表) |
- 方法的详细说明
- 形式参数:在方法声明时用于接收外界传入的数据。(方法定义时)
- 实参:调用方法时实际传给方法的数据。(方法调用时)
- 返回值:执行完毕后,返还给调用它的环境的数据。
- 返回值类型:事先约定的返回值的数据类型,如无返回值,则为void
p 重载
- 重载:一个类中可以定义多个名称相同,但参数列表不同的方法。
重载的方法,实际是完全不同的方法,只是名称相同而已!
- 构成方法重载的条件
- 不同的含义:形参类型,形参个数,形参顺序不同;
- 只有返回值不同不构成方法的重载
- 如:
int a(String str){ }与void a(String str){ }
不构成方法重载
- 如:
- 只有形参的名称不同,不构成方法的重载。
p 递归
- 递归是一种常见的算法思路,在很多算法中都会用到,比如:深度优先搜索(DFS:Depth First Search)
- 递归的基本思想就是"自己调用自己";
- 递归结构包括两个部分:
- 定义递归头:解决:什么时候不调用自身方法。如果没有头,将陷入死循环,也就是递归的结束条件
- 递归体:解决:什么时候需要调用自身方法。
- 递归的缺陷:算法简单是递归的优点之一,但是递归调用会占用大量的系统堆栈,内存好用多,在递归层次多时速度要比循环慢的多,所以在使用时要慎重。
java
public class factorial {
public static long factorial(int n) {
if(n == 1)
{
return 1;
}
else {
return n* factorial(n - 1);
}
}
public static void main(String[] args) {
// 当前时间
long startTime = System.currentTimeMillis();
System.out.println(factorial(20));
// 结束时间
long endTime = System.currentTimeMillis();
System.out.println("递归耗时:"+(endTime - startTime)+"ms");
}
}
p 面向对象 ------面向过程
- 面向过程和面向对象的区别
- 面向过程(C语言)适合简单、不需要协作的事务,重点关注如何执行。
- 面向对象可以帮助我们宏观上把握、从整体上分析整个系统。但是具体到实现部分的微观操作(就是一个个方法),仍然需要面向过程的思路区处理。
- 二者不是对立的,是相辅相成的,面向对象离不开面向过程。
- 面向对象和面向过程思想总结:
- 都是解决问题的思维方式,都是代码组织的方式。
- 面向过程是一种"执行者思维",解决简单问题可以使用面向过程;
- 面向对象是一种"设计者思维",解决复杂。需要协作的问题,可以使用面向对象;
- 面向对象离不开面向过程:
- 宏观上:通过面向对象进行整体设计
- 微观上:执行和处理数据,仍然是面向过程。
p 类
- 类我们叫做class,对象:Object,instance(实例)
- 总结
- 类可以看成一类对象的模版,对象可以看成该类的一个具体实例。
- 类是用于描述同一类型的对象的一个抽象概念,类中定义这一类对象所应具有的共同属性、方法。
- 类的定义方式
java
//每一个源文件必须有且只有一个
public class{}
//并且类名和文件名保持一致!
public class Car {}
class Tyre {}
// 一个Java文件可以同时定义多个
classclass Engine {}
class Seat{}
对于一个类来说,有三种成员:属性field、方法method、构造器constructor.
- 属性(field成员变量)
**属性用于定义该类或该类对象包含的数据或者静态特征。**属性作用范围是整个类体。在定义成员变量时可以对其初始化,如果不对其初始化,Java使用默认的值对其初始化。
数据类型 | 默认值 |
---|---|
整型 | 0 |
浮点型 | 0.0 |
字符型 | "u0000' |
布尔型 | false |
所有引用类型 | null |
- 属性定义格式
[修饰符] 属性类型 属性名 = [默认值];
- 方法
**方法用于定义该类或该类实例的行为特征和功能实现。**方法是类和对象行为特征的抽象。面向对象中,整个程序的基本单位是类,方法是从属于类和对象的。
[修饰符]
方法返回值类型 方法名(形参列表){// n 条语句}
p 简单内存分析
java
/**
* 一个学生类
*
*/
public class Students {
int id;
int age;
String name;
public void study(){
System.out.println("正在学习,勿扰!");
}
public void kickball(){
System.out.println("踢球中,为我加油!");
}
public static void main(String[] args) {
Students s1 = new Students();
System.out.println(s1.id);
System.out.println(s1.name);
s1.id = 1001;
s1.name = "msyy";
System.out.println(s1.id);
System.out.println(s1.name);
s1.study();
s1.kickball();
}
}
P 构造方法(构造器 constructor)
-
构造器用于对象的初始化,而不是创建对象。
-
创建对象的四步:
- 分配对象空间,并将对象成员变量初始化为0或空(null)
- 执行属性值的显示初始化
- 执行构造方法
- 返回对象的地址给相关的变量
-
声明格式
Java[修饰符] 类名(形参列表){ // n条语句 }
-
构造器的4个要点
- 构造器通过
new
关键字调用! - 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用
return
返回某个值。 - 如果我们没有定义构造器,则编译器会自动定义一个无参的构造方法。如果已定义则比编译器不会自动添加!
- 构造器的方法名必须和类名一致!
- 构造器通过
-
课堂练习
定义一个"点(Point)类用来表示二维空间中的点(有两个坐标),要求如下:
可以生成具有特定坐标的点对象。
提供可以计算该"点"距另外一点距离的方法。
java
public class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public double distance(Point p) {
return Math.sqrt(Math.pow(this.x - p.x, 2) + Math.pow(this.y - p.y, 2));
}
public static void main(String[] args) {
Point p1 = new Point(1, 2);
Point p2 = new Point(3, 4);
System.out.println(p1.distance(p2));
}
}
P 构造方法 ------ 内存
P JVM虚拟机内存模型
java虚拟机的内存可以分为三个区域:虚拟机栈(stack)、堆(heap)、方法区(method area)
虚拟机栈(简称:栈)的特点如下:
- 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)
- JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)
- 栈属于线程私有,不能实现线程间的共享!
- 栈的存储特性是"先进后出,后进先出"
- 栈是系统自动分配,速度快!栈是一个连续的内存空间!
堆的特点如下:
-
堆用于存储创建好的对象和数组(数组也是对象)
-
JVM只是一个堆,被所有线程共享。
-
堆是一个不连续的内存空间,分配灵活,速度慢!
-
堆被所有的线程所共享,在堆上的区域,会被垃圾回收器做进一步划分,例如新生代、老年代的划分。
方法区(也是堆)特点如下 -
方法区是JAVA虚拟机规范,可以有不同的实现。
- JDK7以前是"永久代"
- JDK7部分去除"永久代",静态变量、字符串常量池都挪到堆内存中
- JDK8是"元数据空间"和堆结合起来。
-
JVM只有一个方法区,被所有线程共享!
-
方法区实际也是堆,只是用于存储类、常量相关的信息!
-
用来存放程序中永远不变或唯一的内容。(类信息【Class对象】、静态变量、字符串常量等)
-
常量池主要存放常量:如文本字符串、final常量值。
p 程序执行过程的内存分析详解
*这里有个动图传不上来啦 >< *
参数传值机制
JAVA中,方法中所有参数都是"值传递",也就是"传递的是值的副本"。也就是说,我们得到的是"原参数的复印件,而不是原件"。因此,复印件改变不会影响原件。
- 基本数据类型参数的传值
- 传递的是值的副本。副本改变不会影响原件。
- 引用类型参数的传值
- 传递的是值的副本。但是引用类型指的是"对象的地址",因此副本和原参数都指向了同一个"地址",改变了"副本指向地址对象的值",也意味着原参数指向对象的值夜发生了"改变"。
多个对象指向一个地址
java
public class Employee {
private int id;
private String name;
private String job;
private String baseSalary;
private String salary2;
private String hiredate;
private String address;
void Meeting(){
System.out.println("1.8:30打卡");
System.out.println("2.开会");
System.out.println("3.9:00结束");
System.out.println("4.集体喊加油");
}
public static void main(String[] args) {
Employee e1 = new Employee();
e1.id = 1;
e1.name = "abc";
Employee e2 = e1;
System.out.println(e1.id);
System.out.println(e1.name);
e2.id = 2;
e2.name = "def";
System.out.println(e1.id);
System.out.println(e1.name);
}
}
垃圾回收机制(Garbage Colloction)
垃圾回收原理和算法
- 内存管理
- JAVA的内存管理很大程度就是堆中对象的管理,其中包括对象空间的分配和释放。
- 对象空间的分配:使用new 关键字创建对象即可。
- 对象空间的释放:将对象赋值Null即可。
- 垃圾回收过程
任何一种垃圾回收算法一般都要做两件基本事情:
- 发现无用的对象
- 回收无用对象占用的内存空间
垃圾回收机制保证可以将"无用的对象"进行回收。
无用的对象指的是没有任何变量引用该对象。JAVA的垃圾回收器通过相关算法法相无用对象,并进行清除和整理。
垃圾回收相关算法
1. 引用计数法
堆中的每个对象都对应一个引用计数器,当有引用指向这个对象时,引用计数器加1,而当指向该对象的引l用失效时(引l用变为null),引用计数器减1,最后如果该对象的引用计算器的值为0时,则Java垃圾回收器会认为该对象是无用对象并对其进行回收。优点是算法简单缺点是"循环引用的无用对象无法别识别。
java
public class Student {
String name;
Student friend;
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
s1.friend = s2;
s2.friend = s1;
s1 = null;
s2 = null;
}
}
2.引用可达法(根搜索算法)
程序把所有引用关系看作一张图 ,从一个节点点GC ROOT
开始,寻找对应的引用节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引I用到的节点,即无用的节点。
通用的分代垃圾回收机制
JVM调优和Full GC
在对JVM调优的过程中,很大一部分工作就是对于 Full GC 的调节。有如下原因可能 导致Full GC:
- 年老代(Tenured)被写满
- 永久代(perm)被写满
- System.gc()被显示调用
- 上一次GC之后Heap的各域分配策略动态变换。
内存泄露
含义 :指堆内存由于某种原因程序未被释放,造成内存浪费,导致运行速度减慢甚至系统崩溃等。
四种场景:
- 创建大量无用对象:
比如:大量拼接字符串时,使用了String而不是StringBuilder.
java
String str ="";
for(int i = 0 ; i < 10000 ;i++){
str += i; //相当于产生了10000个String对象
}
- 静态集合类的使用
像HashMap、Vector、List
等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象也不能被释放。
- 各种连接对象(IO对象、数据库连接对象、网络连接对象)未关闭
IO流、数据库连接对象、网络连接对象等连接对象属于物理连接,和硬盘或者网络连接,不使用的时候一定要关闭。
- 监听器的使用不当
释放对象时,没有删除相应的监听器。
- 其他要点
- 程序员无权调用垃圾回收器。
- 程序员类可以调用System.gc(),该方法只是通知JVM,并不是运行拦击回收器。尽量少用,会申请Full GC,成本高,影响系统性能。
- Object对象的finalize方法,是JAVA提供给程序员用来释放对象或资源的方法,但是尽量少用。
- 本节作业 (答案会在下一期或者评论区哟)
- 垃圾回收过程一般分为两步,是哪两步?
- 垃圾回收常见的两种算法是什么?
- 堆内存划分成:年轻代、年老代、永久代。垃圾回收器划分成:Minor GC、Major GC、Full GC。这三种垃圾收回器都对应哪些区域?
- 对JVM 调优的过程中,很大一部分工作就是对于FuIl GC 的调节。这句话对吗?
- System.gcO的作用是什么?
今天就学到这里吧!~~~
保护眼睛吧