第八天
1. Static关键字
-
定义:用来修饰的变量和方法,被修饰的成员是属于类的,而不是单单是属于某个对象的。也就是说,既然属于类,就可以不靠创建对象来调用了(但是可以通过对象也可以调用)。
-
位置:类中方法外,修饰成员变量、成员方法、代码块等。
-
该类的每个对象都共享同一个类(静态)变量的值,所以使用对象名调用静态变量也可以,推荐使用类名调用。
-
任何对象都可以更改该类变量的值,但也可以在不创建该类的对象的情况下对类变量进行操作。
-
静态方法中只能使用静态变量。
注意事项:
-
静态变量属于成员变量,局部变量不可以被static进行修饰
原因:当类加载的时候,方法还没有加载
-
被static修饰的内容随着类的加载而加载,类的加载只会加载唯一的一次,因此静态成员也只会加载唯一的一次。
Student类:
public class Student {
String name;
int age;
static String classroom;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getClassroom() {
return classroom;
}
public void setClassroom(String classroom) {
this.classroom = classroom;
}
public Student(String name, int age, String classroom) {
this.name = name;
this.age = age;
this.classroom = classroom;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
public void print () {
System.out.println(name + "=" + age + "=" + classroom);
}
}
测试类:
public class StaticDemo01 {
public static void main(String[] args) {
//创建三个学生对象
Student s1 = new Student("郭靖",18);
Student s2 = new Student("黄蓉",16);
Student s3 = new Student("洪七公",50);
//给学生们安排教室
Student.classroom = "射雕";
//s1.classroom = "射雕";
//打印学生信息
s1.print();
s2.print();
s3.print();
System.out.println("=======================");
//给所有的同学换教室
Student.classroom = "神雕";
//打印学生信息
s1.print();
s2.print();
s3.print();
}
}
静态变量的内存图解:
2. 局部变量、实例变量和静态变量的区别
三种变量的区别:
- 代码中的位置不同:
- 局部变量:方法中或者方法声明上
- 实例变量:类中方法外
- 静态变量:类中方法外
- 内存中的位置不同:
- 局部变量:栈内存
- 实例变量:堆内存
- 静态变量:堆内存== >方法区== >静态区
- 默认值不同:
- 局部变量:没有默认值
- 实例变量:含有默认值
- 静态变量:含有默认值
- 代码中的作用域不同:
- 局部变量:方法中
- 实例变量:类中(静态方法,静态代码块,静态内部类除外)
- 静态变量:类中
- 内存中的生命周期不同:
- 局部变量:随着方法的调用而加载,随着方法的出栈而消失
- 实例变量:随着对象的创建而加载,随着对象的回收而消失
- 静态变量:随着类的加载而加载,随着类的消失而消失
- 最多加载次数不同:
- 局部变量:在栈内存有效下,每调用一次方法就会加载一次
- 实例变量:在堆内存有效下,每创建一次对象就会加载一次
- 静态变量:因为类只能加载唯一的一次,静态变量也只能加载唯一的一次
3. 静态变量的应用案例
Indent类:
public class Indent {
//订单编号
private int id;
//订单商品
private String name;
//订单价格
private double price;
//自动编号变量
private static int num = 211106001;
{
this.id = num++;
}
public Indent() {
//this.id = num++;
}
public Indent(String name, double price) {
//this.id = num++;
this.name = name;
this.price = price;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public void print () {
System.out.println(id + "=" + name + "=" + price);
}
}
测试类:
public class StaticDemo03 {
public static void main(String[] args) {
//创建N个订单对象
Indent it1 = new Indent("尚硅谷牌机械键盘", 9.9);
Indent it2 = new Indent("眼镜", 5000);
Indent it3 = new Indent("假发", 999);
Indent it4 = new Indent();
it4.setName("笔记本电脑");
it4.setPrice(49999);
it1.print();
it2.print();
it3.print();
it4.print();
}
}
4. 静态方法
-
位置:类中方法外
-
格式:修饰符 static 返回值 方法名(形参列表){}
-
作用:当一个类里面的多个实例方法为工具方法时,需要创建对象才能调用这些实例方法,这样会造成堆内存中始终有一块区域被占用,降低内存的使用率。
我们可以将这些工具方法全部声明为static(静态方法),静态方法的好处直接归属于类,不再是对象,无需创建对象,直接拿类名进行调用静态方法。
建议:如果某个类中的所有方法都为静态方法时,将这个类的所有构造器声明为private。
-
调用方式:类名.方法()
注意事项:
- 静态方法可以直接访问类变量和静态方法。
- 静态方法不能直接访问普通成员变量或成员方法。静态方法只能访问静态成员。反之,成员方法可以直接访问类变量或静态方法。
- 静态方法中,不能使用this关键字。
5. 静态代码块
-
位置:类中方法外
-
格式:
static { }
-
作用:
- 自定义工具类加载变量初始化(暂不涉及)
- 初始化自定义常量(暂不涉及)
- 面试题(暂不涉及)
-
注意事项:
- 静态代码块只加载唯一的一次
- 在类中静态代码块可以声明多个,建议写一个即可
- 在静态代码块不可以使用实例成员
- 在静态代码块中不可以使用this关键字,也不可以使用super关键字
6. 单例设计模式
一个类只能得到唯一一个对象。
步骤:
- 首先将构造器私有化,防止测试类new对象;
- 成员变量
- 针对饿汉式,直接将new本类类型的对象;并静态化使得下面的方法可以使用这个对象并将其返回出去;私有化,防止类外通过类名调用修改;
- 针对懒汉式,仅声明私有化、静态化的对象;
- 公有获取唯一对象的方法
- 针对饿汉式:首先得是public,使得可以在类外使用该方法;又因为不能new对象,所以需要通过类型调用,因此加static;
- 针对懒汉式:首先判断静态对象是否为null,再将其返回。
饿汉式:
public class CEO {
private static CEO ceo = new CEO();
private CEO(){}
public static CEO getCeo(){
return ceo;
}
}
懒汉式:
public class Boss {
private static Boss boss;
private Boss(){}
public static Boss getBoss(){
if (boss == null){
boss = new Boss();
}
return boss;
}
}
today code
static:
demo01:static关键字
demo02:局部变量、实例变量和静态变量的区别
demo03:综合案例:单号自动生成
demo04:静态方法
demo05:静态方法的注意事项
demo06:静态代码块
demo07:static关键字的应用:单例设计模式
import:
demo01、demo02:import关键字
api:应用程序接口
scanner:
math:
arrays: