1、对象内存管理
编译好的Java程序运行在JVM中,JVM为Java提供并管理所需要的内存空间。JVM内存分为“堆”、“栈”和“方法区”三个区域,分别用于存储不同的数据。
1.1、堆
(1)、用于存储所有new出来的对象(包括成员变量)。
(2)、成员变量的生命周期
创建(new)对象时存在堆中,对象被垃圾回收器回收时一并消失。
(3)、垃圾回收器(GC)
垃圾回收器(Garbage Collection,GC)是JVM自带的一个线程(自动运行着的程序),用于回收没有任何引用指向的对象。
GC线程并不一定一发现无引用的对象,就立刻回收。一般情况下,当我们需要GC线程即刻回收无用对象时,可以调用System.gc()方法。System.gc()用于建议JVM马上调度GC线程回收资源,具体的实现策略取决于不同的JVM系统。
(4)、内存泄漏
不再使用的对象没有被及时的回收。建议一般当对象不再使用时应及时将引用设置为null。
1.2、栈
(1)、用于存储正在调用中的方法的所有局部变量。注意这里的局部变量没有默认值,必须自行设定初始值。
(2)、调用方法时,在栈中为该方法分配一块对应的栈帧。栈帧中包含所有的局部变量(包括参数),方法调用结束时,栈帧消失 ,局部变量一并消失。
(3)、局部变量的生命周期
调用方法时存在栈中,方法调用结束时与栈帧一并失效。
1.3、方法区
(1)、Java程序运行时,首先会通过类装载器载入类文件的字节码信息(包括方法),经过解析后将其装入方法区。
(2)、方法只有一份,所有的实例对象共用在方法区中的这一份方法定义,通过this来区分具体的引用。
2、继承
2.1、继承的实现与特性
通过extends关键字可以实现类的继承。
子类(sub class)可以继承父类(super class)的成员变量和成员方法,继承具有传递性,同时也可以定义自己的成员变量和成员方法。
Java语言不支持多重继承,一个类只能继承一个父类,但一个类可以有多个子类。
2.2、super关键字
子类的构造方法中必须通过super关键字调用父类的构造方法,这样可以妥善的初始化继承自父类的成员变量。
如果子类的构造方法中没有调用父类的构造方法,Java编译器会自动的加入对父类无参构造方法的调用(如果该父类没有无参的构造方法,会有编译错误)。
3、向上造型
一个子类的对象可以向上造型为父类的类型。即,定义父类型的引用可以指向子类的对象。
父类的引用可以指向子类的对象,但通过父类的引用只能访问父类所定义的成员,不能访问子类扩展的部分。
package xxx;
public class TetrominoTest {
public static void main(String[] args) {
Tetromino t = new T(0,0); //向上转型
printTetromino(t);
Tetromino j = new J(5,4);
printTetromino(j);//先造型再传值
T t1 = new T(4,3);
printTetromino(t1);//传值同时造型
//Tetromino tt = new T(4,3)
}
//向上转型:让子类公用一种类型---父类型
public static void printTetromino(Tetromino tt) { // 打墙+格
Cell[] cells = tt.cells;
for (int i = 0; i < 20; i++) { // 行
for (int j = 0; j < 10; j++) { // 列
boolean flag = true;
for (int k = 0; k < 4; k++) {
if (i == cells[k].row && j == cells[k].col) {
System.out.print("* ");
flag = false;
break;
}
}
if (flag) {
System.out.print("- ");
}
}
System.out.println();
}
}
}
class Tetromino { // 父类--图形类
Cell[] cells;
Tetromino() {
cells = new Cell[4];
}
void drop() { // 下落
for (int i = 0; i < cells.length; i++) {
cells[i].row++;
}
}
void moveLeft() { // 左移
for (int i = 0; i < cells.length; i++) {
cells[i].col--;
}
}
void moveRight() { // 右移
for (int i = 0; i < cells.length; i++) {
cells[i].col++;
}
}
}
class T extends Tetromino {
T() {
this(0, 0); // 调本类构造方法
}
T(int row, int col) {
super(); // 自己不写则默认添加
// 调父类的构造方法
cells[0] = new Cell(row, col);
cells[1] = new Cell(row, col + 1);
cells[2] = new Cell(row, col + 2);
cells[3] = new Cell(row + 1, col + 1);
}
}
class J extends Tetromino {
J() {
this(0, 0);
}
J(int row, int col) {
cells[0] = new Cell(row, col);
cells[1] = new Cell(row, col + 1);
cells[2] = new Cell(row, col + 2);
cells[3] = new Cell(row + 1, col + 2);
}
}