1.面向对象基本使用
Java作为一种面向对象语言。支持以下基本概念:
多态
继承
封装
抽象
类
对象
实例
方法
重载
Java 中的类:类可以看成是创建 Java 对象的模板
通过上图创建一个简单的类来理解下 Java 中类的定义:
/** * Dog类 */ public class Dog { // 类的属性 String breed; int size; String colour; int age; // 类的方法 void eat() { System.out.println("我要吃饭!"); } void run() { } void sleep() { } void name() { } }
一个类可以包含以下类型变量:
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为 static 类型。
JAVA中,属性可以是基本类型,也可以是引用类型🤠
接下来,我们测试以下Dog类:
/** * Dog类的测试类 */ public class DogText { public static void main(String[] args) { // dog只是对象名(对象引用) // new Dog();创建的对象空间(数据)才是真正的对象🤡 Dog dog = new Dog(); // 实例化类对象 dog.breed = "斗牛犬"; dog.size = 3; dog.age = 5; dog.colour = "浅灰色"; // 访问对象的属性 System.out.println(dog.breed); // 访问对象的方法 dog.eat(); // 斗牛犬 // 我要吃饭! } }
2.对象内存布局
分析以下的代码内存布局:
图示分析:
在方法区首先要做的事情是加载类的信息,包括类的属性和方法🎈
字符串常量池设计思想:
字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建字符串,极大程度地影响程序的性能
JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化
为字符串开辟一个字符串常量池,类似于缓存区
创建字符串常量时,首先查看字符串常量池是否存在该字符串
存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中
在JDK6.0及之前版本,字符串常量池存放在方法区中,在JDK7.0版本以后,字符串常量池被移到了堆中了。至于为什么移到堆内,大概是由于方法区的内存空间太小了。在HotSpot VM里实现的string pool功能的是一个StringTable类,它是一个Hash表,默认值大小长度是1009;这个StringTable在每个HotSpot VM的实例只有一份,被所有的类共享。字符串常量由一个一个字符组成,放在了StringTable上🌕
3.对象分配机制
对象赋值:
// 类赋值,假设之前的p1类已经创建 Person p2 = p1; // 把p1赋值给p2,本质上是内存的指向
内存分析图示:
4.Java创建对象流程
java内存结构
流程分析
我们以下面的示例代码进行分析:
- 加载Person类信息(属性和方法信息,只会加载一次)
- 在堆中分配空间,进行默认初始化
- 把地址赋值给p,p就指向对象
- 进行指定初始化(给对象的属性赋值)
5.成员方法
普通方法
此方法只是输出一句话
public void speak(){ System.out.println("我是一个人"); }
可以接收参数的方法
方法可以接受一个或若干个的形参列表,同时在调用的时候需要提供相应的值
// 计算 1 -- n 的和 public void cal(int n){ int res = 0; for (int i = 1; i <= n; i++) { res += i; } System.out.println(res); }
测试类测试方法:
person.cal(100); // 调用一个方法,并传给该方法一个值 // 5050
可以返回值的方法
方法同时还支持返回值的操作
// 计算 a + b public int add(int a, int b) { return a + b; }
测试类测试方法:
int addRes = person.add(10, 20); System.out.println(addRes); // 30
方法的调用机制
现在我们来分析以下如下代码块的内存调用机制
内存分析图:
- 当程序执行到方法时,就会开辟一个独立的空间(栈空间)
- 当方法执行完毕时,或者执行return语句时,就会返回到调用方法的地方。返回后继续执行方法后面的代码
- 方法调用结束后,栈中创建的空间会被自动回收