文章目录
通过前两篇的学习,我们已经对类和对象有了初步的认识,本篇将介绍static和代码块,相较前两篇来说,本篇的难度也有所增加,但我依然会详细地介绍,让你了解更多的细枝末节!💪💪
7. static成员
7.1 再谈学生类
使用前文中介绍的学生类 实例化三个对象s1,s2,s3,每个对象都有自己特定的名字、性别、年龄、学分绩点等成员信息,这些信息就是对不同学生来进行描述的,如下所示:
假设三个同学是同一个班的,那么他们上课肯定是在同一个教室,那既然在同一个教室,那能否给类中再加一个成员变量,来保存同学上课时的教室呢?答案是不行的。
之前在Student类中定义的成员变量,每个对象中都会包含一份(称之为实例变量),因为需要使用这些信息来描述具体的学生。而现在要表示学生上课的教室,这个教室的属性并不需要每个学生对象中都存储一份,而是需要让所有的学生来共享。在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。
🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉
7.2 修饰成员变量
static修饰的成员变量,称为静态成员变量 / 类变量,静态成员变量最大的特性:不属于具体的某个对象,是所有对象所共享的。
静态的成员变量和静态的成员方法,都不依赖于对象,因为它们是类变量,可以通过类名访问,静态的成员变量放在方法区上。
运行结果:
1、普通的成员方法当中,是可以使用静态的成员变量的。
2、静态的成员方法当中,不能访问非静态的成员(成员变量和成员方法)–> 非静态的成员是依赖于对象的。
因为要访问非静态的成员必须先创建对象,而静态成员不需要创建对象,还没有创建对象时,静态的成员就已经存在了,那么静态方法里自然也不能访问非静态的依赖于对象的成员。
【静态成员变量特性】
- 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
- 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问 (使用对象访问合法但不合理)
- 在逻辑上,方法区和堆是同等级的,在实际实现上,方法区是堆的一部分
- 类变量存储在方法区当中
- 生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)
以调试的方式运行代码,在监视窗口中可以看到,静态成员变量并没有存储到具体的某个对象中。
🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉
7.3 static修饰成员方法
Java中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的。
输出:Bit306
【静态方法特性】
- 不属于某个具体的对象,是类方法
- 可以通过对象调用,也可以通过类名.静态方法名(…)方式调用,更推荐使用后者
- 静态方法没有隐藏的this引用参数,因此不能在静态方法中访问任何非静态成员变量
- 静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用
- 静态方法无法重写,不能用来实现多态(此处暂时不用管,后序多态位置详细讲解)。
🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉
7.4 static成员变量初始化
静态成员变量的初始化分为两种:就地初始化和静态代码块
- 就地初始化
就地初始化指的是:在定义时,直接给出初始值。
- 静态代码块初始化
那什么是代码块呢?继续往后看:>~~
🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉
8. 代码块
8.1 代码块概念以及分类
使用 {} 定义的一段代码称为代码块。根据代码块定义的位置以及关键字,又可分为以下四种:
1、实例代码块/构造代码块
2、静态代码块
3、本地代码块/普通代码块(用不到)
4、同步代码块(目前用不到)
🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉
8.2 普通代码块
普通代码块:定义在方法中的代码块
这种用法很少见,几乎不会用。
🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉
8.3 构造代码块(实例代码块)
构造代码块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。一般用于初始化实例成员变量(非静态)
运行结果:
【注意事项】 实例代码块优先于构造方法执行,因为编译完成后,编译器会将实例代码块中的代码拷贝到每个构造方法第一条语句前。
🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉
8.4 静态代码块
使用static定义的代码块称为静态代码块,一般用于初始化静态成员变量。
运行结果:
可以发现,静态代码块最先执行。
【注意事项】
1、静态代码块不管生成多少个对象,其只会执行一次
2、静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
3、Java代码在经过编译器编译之后,如果要运行必须先要经过类加载子系统加载到JVM中才能运行。在加载阶段:
在链接阶段第二步准备中会给静态成员变量开辟空间,并设置为默认值,在初始化阶段,会执行静态代码块中的代码。(了解:关于类加载过程后序JVM中会详细讲解)
如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序(从上到下)依次合并,(从上到下依次执行)最终放在生成的构造方法中,该方法在类加载时调用,并且只调用一次。
运行结果:
实例代码块只有在创建对象时才会执行。
🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉
总结
本篇主要讲了static的用法和代码块,static修饰的成员是静态的,静态的成员是不依赖于对象的,可以直接通过类名访问,不需要创建对象。静态的成员变量放在方法区(不在堆区),是所有对象所共享的,非静态的成员方法中可以访问静态的成员,静态的成员方法中不能访问非静态的成员。
又讲了三种代码块,其中实例代码块优先于构造方法执行,静态代码块优先于实例代码块执行,无论创建多少个对象,静态代码块都只会执行一次,若有多个静态代码块,则按定义的顺序从上到下依次执行。
下篇就是类和对象的最终篇了,也是最抽象的一篇,所以单独分为一篇来写。类和对象的概念很多,知识点很杂且较为抽象,所以分为了四篇,最后希望大家看完后给个三连哦~~
版权归原作者 夏.冬 所有, 如有侵权,请联系我们删除。