一 内存图
一个对象的内存图
注意,如果调用方法,先在栈中加载,如果调用完毕,就在栈中消失。最终main方法结束,main方法在栈中消失。
二 创建对象做了哪些事情
class Student{
private String name = "林青霞";
private int age = 27;
public Student(){
name = "刘意";
age = 30;
}
}
Student s = new Student();做了哪些事情?
(1)把Student.class文件加载到内存
(2)在栈内存为s开辟空间
(3)在堆内存为学生对象申请空间
(4)给学生的成员变量进行默认初始化。null,0
(5)给学生的成员变量进行显示初始化。林青霞,27
(6)通过构造方法给成员变量进行初始化。刘意,30
(7)对象构造完毕,把地址赋值给s变量
三 成员变量与局部变量
成员变量和局部变量的区别
(1)在类中的位置不同
成员变量:类中方法外
局部变量:方法定义中或者方法声明上
(2)在内存中的位置不同
成员变量:在堆中
局部变量:在栈中
(3)生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
(4)初始化值不同
成员变量:有默认值
局部变量:没有默认值,必须定义,赋值,然后才能使用
四 static关键字
1)静态的特点
A:随着类的加载而加载
B:优先于对象存在
C:静态只能访问静态(代码测试过)
2)静态的内存图
对象的初始化过程
1、加载Demo.class文件进方法区,并进行空间分配。
2、如果有静态变量,先默认初始化,显示初始化。
3、如果有静态代码块,要执行,仅一次。
4、通过new在堆内存中开辟空间,并明确首地址。
5、对对象中的属性进行默认初始化。
6、调用对应的构造函数进行初始化。
7、构造函数内部。
(1)调用父类构造函数super();
(2)成员变量的显示初始化。
(3)构造代码块初始化。
(4)构造函数内容自定义内容初始化。
8、对象初始化完毕后,将地址赋值给引用变量。
3)静态变量和成员变量的区别
A:所属不同
静态变量:属于类,类变量
成员变量:属于对象,对象变量,实例变量
B:内存位置不同
静态变量:方法区的静态区
成员变量:堆内存
C:生命周期不同
静态变量:静态变量是随着类的加载而加载,随着类的消失而消失
成员变量:成员变量是随着对象的创建而存在,随着对象的消失而消失
D:调用不同
静态变量:可以通过对象名调用,也可以通过类名调用
成员变量:只能通过对象名调用
4)注意事项
因为静态先存在于内存中无法访问后来的对象的中的数据,所以静态无法访问非静态。而且内部无法书写this、super等关键字,因为这时对象有可能不存在,this没有任何指向。
5)main方法是静态的
public:权限最大
static:不用创建对象调用
void:返回值给jvm没有意义
main:就是一个常见的名称。
String[] args:可以接收数据,提供程序的灵活性
格式:java MainDemo hello world java
java MainDemo 10 20 30
3、静态代码块
类一加载,需要做一些动作。不一定需要对象。
(1)特点:随着类的加载而执行,仅执行一次。
(2)作用:给类进行初始化。
public class StaticDemo {
public static void main(String[] args) {
Demo.show();
Demo.show();
}
}
class Demo{
static int x = 9; //静态变量有两次初始化。 一次默认初始化,一次显示初始化。
static{ //静态代码块。在静态变量显示初始化以后在执行。
System.out.println("类加载就执行的部..."+x);
}
static void show(){
System.out.println("show run");
}
}
四、封装
封装步骤
(1)修改属性的可见性
(2)创建get/set等可用于操作属性的方法
private是封装的一种体现。
封装:类,方法,private修饰成员变量
(被private修饰的后的成员只能在本类中被访问)
五 代码块
1)用{}括起来的代码。
2)分类:
A:局部代码块
用于限定变量的生命周期,及早释放,提高内存利用率。
B:构造代码块
把多个构造方法中相同的代码可以放到这里,每个构造方法执行前,首先执行构造代码块。
C:静态代码块
对类的数据进行初始化,仅仅只执行一次。
六 继承
1)继承的注意事项:
A:子类不能继承父类的私有成员
2)Java继承中的构造方法
a:子类的构造方法默认会去访问父类的无参构造方法
是为了子类访问父类数据的初始化
b:父类中如果没有无参构造方法,怎么办?
子类通过super去明确调用带参构造
子类通过this调用本身的其他构造,但是一定会有一个去访问了父类的构造
让父类提供无参构造
3)Override和Overload的区别?Overload是否可以改变返回值类型?
方法重写:在子类中,出现和父类中一模一样的方法声明的现象。
方法重载:同一个类中,出现的方法名相同,参数列表不同的现象。
方法重载能改变返回值类型,因为它和返回值类型无关。
(Override:方法重写Overload:方法重载)
4)案例:
代码1:
/*
* 结果是:
静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi
*
*/
public class ExtendsDemo {
public static void main(String[] args) {
Zi z = new Zi();
}
}
class Fu{
static{
System.out.println("静态代码块Fu");
}
{
System.out.println("构造代码块Fu");
}
public Fu(){
System.out.println("构造方法Fu");
}
}
class Zi extends Fu{
static{
System.out.println("静态代码块Zi");
}
{
System.out.println("构造代码块Zi");
}
public Zi(){
System.out.println("构造方法Zi");
}
}
是视频的8.20
代码2:
/*
* 结果是: YXYZ
*
*/
public class ExtendsDemo {
public static void main(String[] args) {
new Z();
}
}
class X{
Y b = new Y();
X(){
System.out.println("X");
}
}
class Y{
Y(){
System.out.println("Y");
}
}
class Z extends X{
Y y = new Y();
Z(){
// super();
System.out.println("Z");
}
}
视频是8.21