Java基础(十):关键字static、代码块、关键字final
Java基础(十):关键字static、代码块、关键字final
Java基础系列文章Java基础(一):语言概述Java基础(二):原码、反码、补码及进制之间的运算Java基础(三):数据类型与进制Java基础(四):逻辑运算符和位运算符Java基础(五):流程控制语句Java基础(六):数组Java基础(七):面向对象编程Java基础(八):封装、继承、多态性Java基础(九):Object
Java基础(十):关键字static、代码块、关键字final
Java基础系列文章
Java基础(一):语言概述 | Java基础(二):原码、反码、补码及进制之间的运算 | Java基础(三):数据类型与进制 | Java基础(四):逻辑运算符和位运算符 |
---|---|---|---|
Java基础(五):流程控制语句 | Java基础(六):数组 | Java基础(七):面向对象编程 | Java基础(八):封装、继承、多态性 |
Java基础(九):Object 类的使用 | Java基础(十):关键字static、代码块、关键字final | Java基础(十一):抽象类、接口、内部类 | Java基础(十二):枚举类 |
Java基础(十三):注解(Annotation) | Java基础(十四):包装类 | Java基础(十五):异常处理 | Java基础(十六):String的常用API |
Java基础(十七):日期时间API | Java基础(十八):java比较器、系统相关类、数学相关类 | Java基础(十九):集合框架 | Java基础(二十):泛型 |
Java基础(二十一):集合源码 | Java基础(二十二):File类与IO流 | Java基础(二十三):反射机制 | Java基础(二十四):网络编程 |
Java基础(二十五):Lambda表达式、方法引用、构造器引用 | Java基础(二十六):Java8 Stream流及Optional类 |
一、关键字static
- 如果想让一个成员变量被类的
所有实例所共享
,就用static修饰即可,称为类变量(或类属性)!!! - 在类中声明的实例方法
- 在类的外面必须要先创建对象,才能调用
- 但是有些方法的调用者和当前类的对象无关,这样的方法通常被声明为
类方法
- 由于不需要创建对象就可以调用类方法,从而简化了方法的调用
static关键字
- 使用范围:可用static修饰属性、方法、代码块、内部类
- 被修饰后的成员具备以下特点:
- 随着类的加载而加载
- 优先于对象存在
- 修饰的成员,被所有对象所共享
- 访问权限允许时,可不创建对象,直接被类调用
1、静态变量
静态变量的特点
- 静态变量值是所有对象共享
- 静态变量在本类中,可以在任意方法、代码块、构造器中直接使用
- 如果权限修饰符允许,在其他类中可以通过“
类名.静态变量
”直接访问,也可以通过“对象.静态变量
”的方式访问 (但是更推荐使用类名.静态变量的方式) - 静态变量的get/set方法也静态的,当局部变量与静态变量
重名时
,使用“类名.静态变量
”进行区分
对比静态变量与实例变量
- 个数
- 静态变量:在内存空间中只有一份,被类的多个对象所共享
- 实例变量:类的每一个实例(或对象)都保存着一份实例变量
- 内存位置
- 静态变量:jdk6及之前:存放在方法区。 jdk7及之后:存放在堆空间
- 实例变量:存放在堆空间的对象实体中
- 加载时机
- 静态变量:随着类的加载而加载,由于类只会加载一次,所以静态变量也只有一份
- 实例变量:随着对象的创建而加载。每个对象拥有一份实例变量
- 调用者
- 静态变量:可以被类直接调用,也可以使用对象调用
- 实例变量:只能使用对象进行调用
- 消亡时机
- 静态变量:随着类的卸载而消亡
- 实例变量:随着对象的消亡而消亡
举例
2、静态方法
静态方法的特点
- 在static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构
- 静态方法可以被子类继承,但不能被子类重写
- 因为不需要实例就可以访问static方法,因此static方法内部不能有this,也不能有super。如果有重名问题,使用“类名.”进行区别
- 由于JVM需要调用类的main()方法,所以该方法的访问权限必须是
public
- 又因为JVM在执行main()方法时不必创建对象,所以该方法必须是
static
的 - 该方法接收一个String类型的数组参数,该数组中保存执行Java命令时传递给所运行的类的参数
- 又因为main() 方法是静态的,我们不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员
举例:
1、静态代码块
- 随着类的加载而执行
- 由于类的加载只会执行一次,进而静态代码块的执行,也只会执行一次
- 作用:用来初始化类的信息
- 内部可以声明变量、调用属性或方法、编写输出语句等操作
- 静态代码块的执行要先于非静态代码块的执行
- 如果声明有多个静态代码块,则按照声明的先后顺序执行
- 静态代码块内部只能调用静态的结构(即静态的属性、方法),不能调用非静态的结构(即非静态的属性、方法)
2、非静态代码块
- 随着对象的创建而执行
- 每创建当前类的一个实例,就会执行一次非静态代码块
- 作用:用来初始化对象的信息
- 内部可以声明变量、调用属性或方法、编写输出语句等操作
- 静态代码块的执行要先于非静态代码块的执行
- 如果声明有多个非静态代码块,则按照声明的先后顺序执行
- 非静态代码块内部可以调用静态的结构(即静态的属性、方法),也可以调用非静态的结构(即非静态的属性、方法)
、实例变量赋值顺序
- 先加载父类,通过构造器第一行,隐藏的super()方法父类
- 代码块在构造器之前执行
- 显示赋值和代码块中赋值顺序,由先后顺序决定
代码语言:javascript代码运行次数:0运行复制举例1
class Root{
static{
println("Root的静态初始化块");
}
{
println("Root的普通初始化块");
}
public Root(){
println("Root的无参数的构造器");
}
}
class Mid extends Root{
static{
println("Mid的静态初始化块");
}
{
println("Mid的普通初始化块");
}
public Mid(){
println("Mid的无参数的构造器");
}
public Mid(String msg){
//通过this调用同一类中重载的构造器
this();
println("Mid的带参数构造器,其参数值:"+ msg);
}
}
class Leaf extends Mid{
static{
println("Leaf的静态初始化块");
}
{
println("Leaf的普通初始化块");
}
public Leaf(){
//通过super调用父类中有一个字符串参数的构造器
super("尚硅谷");
println("Leaf的构造器");
}
}
public class LeafTest{
public static void main(String[] args){
new Leaf();
//new Leaf();
}
}
结果:
代码语言:javascript代码运行次数:0运行复制Root的静态初始化块
Mid的静态初始化块
Leaf的静态初始化块
Root的普通初始化块
Root的无参数的构造器
Mid的普通初始化块
Mid的无参数的构造器
Mid的带参数构造器,其参数值:尚硅谷
Leaf的普通初始化块
Leaf的构造器
- 先加载父类静态,再到子类静态
- 先顺序执行父类普通代码块、构造器,再执行子类普通代码块、构造器
举例2
- 第一个静态代码中的x作用域只在当前代码块中,与静态成员变量x是两个变量
public class Test02 {
static int x, y, z;
static {
int x = 5;
x--;
}
static {
x--;
}
public static void method() {
y = z++ + ++z;
}
public static void main(String[] args) {
println("x=" + x);
z--;
method();
println("result:" + (z + y + ++z));
}
}
代码语言:javascript代码运行次数:0运行复制举例
public class Test0 {
public static void main(String[] args) {
Sub s = new Sub();
}
}
class Base{
Base(){
method(100);
}
{
println("base");
}
public void method(int i){
println("base : " + i);
}
}
class Sub extends Base{
Sub(){
(70);
}
{
println("sub");
}
public void method(int j){
println("sub : " + j);
}
}
结果:
代码语言:javascript代码运行次数:0运行复制base
sub : 100
sub
base : 70
- 父类Base的构造函数中调用method,其实是
- 当前对象是sub,那么method则是被重写的method
- final:最终的,不可更改的
1、final修饰类
- 表示这个类
不能被继承
,没有子类。提高安全性,提高程序的可读性 - 例如:String类、System类、StringBuffer类
final class Eunuch{//太监类
}
class Son extends Eunuch{//错误
}
2、final修饰方法
- 表示这个方法
不能被子类重写
- 例如:Object类中的getClass()
class Father{
public final void method(){
println("father");
}
}
class Son extends Father{
public void method(){//错误
println("son");
}
}
、final修饰变量
- final修饰某个变量(成员变量或局部变量),一旦赋值,它的值就
不能被修改
,即常量,常量名建议使用大写字母 - 例如:final double MY_PI = .14
- 如果某个成员变量用final修饰后,没有set方法,并且必须初始化(可以显式赋值、或在初始化块赋值、实例变量还可以在构造器中赋值)
- 修饰成员变量
public final class Test {
public static int totalumber = 5;
public final int ID;
public Test() {
ID = ++totalumber; // 可在构造器中给final修饰的“变量”赋值
}
public static void main(String[] args) {
Test t = new Test();
println(t.ID);
}
}
- 修饰局部变量
public class TestFinal {
public static void main(String[] args){
final int MI_SCORE ;
MI_SCORE = 0;
final int MAX_SCORE = 100;
MAX_SCORE = 200; //非法
}
}
- 错误演示
class A {
private final String IFO = "atguigu"; //声明常量
public void print() {
//The final field A.IFO cannot be assigned
//IFO = "尚硅谷";
}
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-02-24,如有侵权请联系 cloudcommunity@tencent 删除static变量基础javafinal #感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
上传时间: 2025-07-20 18:22:32
推荐阅读
留言与评论(共有 10 条评论) |
本站网友 春秋争霸 | 4分钟前 发表 |
也可以通过“对象.静态变量”的方式访问 (但是更推荐使用类名.静态变量的方式)静态变量的get/set方法也静态的 | |
本站网友 网上房贷计算器 | 20分钟前 发表 |
调用属性或方法 | |
本站网友 石菖蒲 | 24分钟前 发表 |
再到子类静态先顺序执行父类普通代码块 | |
本站网友 丹凤眼是什么样的 | 26分钟前 发表 |
也只会执行一次作用:用来初始化类的信息内部可以声明变量 | |
本站网友 深圳罗湖区 | 11分钟前 发表 |
补码及进制之间的运算Java基础(三):数据类型与进制Java基础(四):逻辑运算符和位运算符Java基础(五):流程控制语句Java基础(六):数组Java基础(七):面向对象编程Java基础(八):封装 | |
本站网友 叶世荣 | 23分钟前 发表 |
因此static方法内部不能有this | |
本站网友 深圳市科技工贸和信息化委员会 | 1分钟前 发表 |
100 sub base | |
本站网友 云溪公园 | 18分钟前 发表 |
则按照声明的先后顺序执行静态代码块内部只能调用静态的结构(即静态的属性 | |
本站网友 李桂莲 | 12分钟前 发表 |
final修饰变量final修饰某个变量(成员变量或局部变量) |