多张图做网站背景,2345天气王,南京做网站南京乐识专业,百度文章收录提交入口✅作者简介#xff1a;大家好#xff0c;我是Leo#xff0c;热爱Java后端开发者#xff0c;一个想要与大家共同进步的男人#x1f609;#x1f609; #x1f34e;个人主页#xff1a;Leo的博客 #x1f49e;当前专栏#xff1a;每天一个知识点 ✨特色专栏#xff1a…
✅作者简介大家好我是Leo热爱Java后端开发者一个想要与大家共同进步的男人 个人主页Leo的博客 当前专栏每天一个知识点 ✨特色专栏 MySQL学习 本文内容第07天 Static关键字作用及用法 ️个人小站 个人博客欢迎大家访问 个人知识库 知识库欢迎大家访问
1. 概述 Static是静态修饰符什么叫静态修饰符呢大家都知道在程序中任何变量或者代码都是在编译时由系统自动分配内存来存储的而所谓静态就是指在编译后所分配的内存会一直存在直到程序退出内存才会释放这个空间也就是只要程序在运行那么这块内存就会一直存在。这样做有什么意义呢在Java程序里面所有的东西都是对象而对象的抽象就是类对于一个类而言如果要使用他的成员那么普通情况下必须先实例化对象后通过对象的引用才能够访问这些成员但是用static修饰的成员可以通过类名加“.”进行直接访问。 官方解释 静态变量Static Variable在计算机编程领域指在程序执行前系统就为之静态分配也即在运行时中不再改变分配情况存储空间的一类变量。与之相对应的是在运行时只暂时存在的自动变量即局部变量与以动态分配方式获取存储空间的一些对象其中自动变量的存储空间在调用栈上分配与释放。选自维基百科
如何理解为什么要这样做例子
解释
首先先了解一下Java的内存分配 Java 把内存分为栈内存和堆内存其中栈内存用来存放一些基本类型的变量、数组和对象的引用堆内存主要存放一些对象。 什么是句柄 自己理解的话,其实就是类似于对这些静态的成员进行编号。
那为什么要这样做呢 在 JVM 加载一个类的时候若该类存在 static 修饰的成员变量和成员方法则会为这些成员变量和成员方法在固定的位置开辟一个固定大小的内存区域有了这些“固定”的特性那么 JVM 就可以非常方便地访问他们。同时如果静态的成员变量和成员方法不出作用域的话它们的句柄都会保持不变。同时 static 所蕴含“静态”的概念表示着它是不可恢复的即在那个地方你修改了他是不会变回原样的你清理了他就不会回来了。 可能这些有些偏于理论下面我们通过一些代码示例来进一步了解Static关键字
2. 修饰成员属性
当我们需要在一个类class中定义一个属性为公共的属性就好比说我们需要这个属性是所有类都是共有的并且这个属性的值是同一个。
package com.cisyam.testStatic;/*** author : Leo* version 1.0* date 2023/8/18 11:06* description :*/
class Book{// 设置一个默认的值static String pub 清华大学出版社;// 用来和 static 作为对比String description 描述;// Book 类正常的属性private String title;private double price;// Book 的构造类public Book(String title, double price) {this.title title;this.price price;}// 获取 Book 的信息public void getInfo(){System.out.println(图书名称 this.title 价格为 this.price 出版社为 pub 描述 this.description);}
}public class Test {public static void main(String[] args) {// 实例化三个Book类Book book1 new Book(Android开发实战, 69.8);Book book2 new Book(Java EE开发实战, 49.8);Book book3 new Book(Java 开发教程, 79.8);// 在没有设置 pub 属性的情况下输出book1.getInfo();book2.getInfo();book3.getInfo();System.out.println(————————————————————无敌分割线————————————————————);// 我们给 book1 设置一个 pub 属性Book.pub 中信出版社;book1.description 这本书很牛逼看了你就知道;book1.getInfo();book2.getInfo();book3.getInfo();}
}控制台输出 从控制台输出的结果可以看到
如果给 属性 赋默认值在上面的例子中是(description 和 pub)输出的结果为都是默认的。当我们修改了类中 static 关键字声明的属性那么只要修改了一次那么其他所有的对象的这个属性都给修改了。
通过类调用 static 声明的属性 但是基于上面的代码我们发现如果是其中的一个类对象就改变了所有的对象的属性这样子操作是不是感觉不是特别好然后在Java中如果是使用 static 声明的属性值是可以直接通过类调用的。 public class Test {public static void main(String[] args) {// 实例化三个Book类Book book1 new Book(Android开发实战, 69.8);Book book2 new Book(Java EE开发实战, 49.8);Book book3 new Book(Java 开发教程, 79.8);// 在没有设置 pub 属性的情况下输出book1.getInfo();book2.getInfo();book3.getInfo();System.out.println(————————————————————无敌分割线————————————————————);// 我们使用 Book 类直接调用pubBook.pub 中信出版社;book1.description 这本书很牛逼看了你就知道;book1.getInfo();book2.getInfo();book3.getInfo();}
}没有实例化类时调用 static 属性
package com.cisyam.testStatic;/*** author : Leo* version 1.0* date 2023/8/18 11:19* description :*/
class Book2{// 设置一个默认的值static String pub 清华大学出版社;// 用来和 static 作为对比String description 描述;// Book 类正常的属性private String title;private double price;// Book 的构造类public Book2(String title, double price) {this.title title;this.price price;}// 获取 Book 的信息public void getInfo(){System.out.println(图书名称 this.title 价格为 this.price 出版社为 pub 描述 this.description);}
}public class Test3 {public static void main(String[] args) {// 在没有实例化对象时就调用System.out.println(Book.pub);// 没事实例化对象的时候去给static属性赋值上默认值Book2.pub 北京大学出版社;System.out.println(Book.pub);// 新建一个类输入 pub 属性Book2 book new Book2(Java, 88);book.getInfo();}
}控制台输出 由此我们看出在没有实例化对象的时候就可以直接通过类去掉用 static属性并且还可以修改 static 的属性。static 属性声明虽然是在类的结构中但是并不受到对象的控制是独立存在的。
static 属性与非 static 属性的区别 static 声明的属性和普通属性非 static 属性最大的区别在于保存的内存区域不同。static 所修饰的在静态数据区。而不是在堆和栈。 static 属性与非 static 属性还有一个最大的区别就是在于所有非 static 属性必须产生实例化之后才可以访问但是static 属性不受实例化对象的控制。也就是说在没有产生实例化对象的情况下依然可以使用 static 对象。
3. 修饰成员方法
说明
方法本来就是存放在类的定义当中的。static修饰成员方法的作用是可以使用类名.方法名的方式操作方法避免了先要new出对象的繁琐和资源消耗。
package com.cisyam.testStatic;/*** author : Leo* version 1.0* date 2023/8/18 11:19* description :*/
class Test2{public static void sayHello(String name) {System.out.println(Hello, name);}
}public class Demo {public static void main(String[] args) {Test2.sayHello(Leo);}
}控制台输出 4. 修饰代码块
说明
**static **{ }就是静态块当类加载器载入类的时候这一部分代码被执行常用于对静态变量进行初始化工作。当其他代码用到这个类类加载器才会将它载入。
代码只能执行一次不能再调用。在静态块中可以访问静态变量调用静态方法。
如果去掉static{ }中的代码则会在创建类对象的时候才执行相当于把这部分代码复制到各个构造函数中这样可以实现块中的内容在多个构造函数中的复用。
package com.cisyam.testStatic;/*** author : Leo* version 1.0* date 2023/8/18 11:29* description :*/
class Test4{static {System.out.println(静态代码块执行);}{System.out.println(普通代码块执行);}public Test4(){System.out.println(This is Test());}public Test4(String string){System.out.println(This is Test(String string));}
}public class Demo2 {public static void main(String[] args) {System.out.println(------------------------);Test4 test1 new Test4();System.out.println(------------------------);Test4 test2 new Test4(Hello);}
}
控制台输出 5. 修饰内部类
static 不能修饰普通类但可以修饰内部类。原因如下
static 修饰的东西被我们成为类成员它会随着类的加载而加载比如静态代码块静态成员静态方法(这里只是加载并没有调用)等等。若把一个Class文件中的外部类设为static那目的何在呢难道让这个类随着应用的启动而加载吗如果我在这次使用过程中根本没有使用过这个类那么是不是就会浪费内存。这样来说设计不合理总而言之设计不合理的地方Java是不会让它存在的。
为什么内部类可以使用 static 修饰呢因为内部类算是类的成员了如果我们没有使用静态来修饰那么我们在创建内部类的时候就需要先有一个外部类的对象如果我们一直在使用内部类那么内存中就会一直存在外部类的引用而我们有时候只需要使用内部类不需要外部类那么还是会浪费内存甚至会造成内存溢出。使用 static修饰内部类之后内部类在创建对象时就不需要有外部类对象的引用了。
package com.cisyam.testStatic;public class Singleton {private static class SingletonHolder {private static final Singleton INSTANCE new Singleton();}private Singleton (){}public static final Singleton getInstance() {return SingletonHolder.INSTANCE;}
}class Demo3 {public static void main(String[] args) {Singleton singleton Singleton.getInstance();System.out.println(singleton);}}
6. static加载顺序
首先思考下边程序是否能编译通过若可以编译通过那么执行结果是什么
package com.cisyam.testStatic;/*** author : Leo* version 1.0* date 2023/8/18 11:38* description :*/
public class User {private static String name;public void setName(String name) {this.name name;}public static String getName() {return User.name;}
}
public class Test6 {public static void main(String[] args) {User user new User();user.setName(Leo);System.out.println(user User.getName());}
}控制台输出 从上述结果可见实例对象可以访问访问类变量。