基本用法

静态成员变量、方法

static修饰的成员变量为静态成员变量,在内存中只存储一份,可以被共享修改、操作,属于类,随类产生,类加载时被初始化。

成员变量分为静态成员变量和示例成员变量:

  • 静态成员变量:有static修饰,属于类,可使用Class.Name(推荐) 或 Project.Name(不推荐)访问,常用表示在线人数等需要共享的信息
  • 实例成员变量:无static修饰,存在每个对象中,使用 Project.Name访问,常表示年龄、姓名等属于每个对象的信息

静态成员方法与静态成员变量一样,使用场景如下:

  • 静态成员方法:实现一个通用的功能,比如登录
  • 示例成员方法:表示对象自己的行为,如添加好友、吃饭、睡觉

静态成员变量内存图:

image-20220106120926680

静态成员方法内存图:

image-20220106122029190

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class User {
// 在线人数,静态成员变量
public static int onlineNumber;
// 静态成员方法
public static void login(){
System.out.println("静态成员方法");
}

public static void main(String[] args) {
int num = User.onlineNumber;
System.out.println(num);
User.test();
}
}

使用静态方法定义工具类

利用static修饰符创建静态成员方法,并将构造器私有化,即可实现静态方法只能被类调用访问,以此实现工具类。

一般将通用重复使用的功能创建为工具类,一生成验证码为例:

封装实现工具类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Random;
/*
* 工具类,封装生成只当长度验证码
* */
public class VerifyCodeTool {

// 构造器私有化
private VerifyCodeTool() {
}

public static String createVerifyCode(int length){
String charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random = new Random();
String verifyCode = "";
for (int i = 0; i < length; i++) {
// 生成随机下标
int index = random.nextInt(charset.length());
// 根据下标取字符,拼接
verifyCode += charset.charAt(index);
}
return verifyCode;
}
}

调用工具类,生成验证码:

1
2
3
4
5
6
7
8
9
10
11
12
import java.util.Scanner;

public class Login {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("输入验证码长度:");
int length = scanner.nextInt();
// 调用工具类生成验证码
String verifyCode = VerifyCodeTool.createVerifyCode(length);
System.out.println(verifyCode);
}
}

image-20220106211308698

使用静态方法定义数组处理工具类

创建一个数组处理工具类,要求将整数数组输出为字符串格式:[1, 2, 3, 4],需要考虑null和空数组

ArrayUitls工具类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
* 将整数数组输出为 [1, 2, 3]的字符串形式
* */
public class ArrayUtils {

private ArrayUtils() {
}

public static String toString(int[] array){
String arrayString = "null";
if (array != null){
arrayString = "[";
for (int i = 0; i < array.length; i++) {
arrayString += (i == array.length - 1 ? array[i] : array[i] + ", ");
}
arrayString += "]";
}
return arrayString;
}
}

image-20220106215432511

static注意事项

  • 静态方法只能访问静态成员,不能访问实例成员,因为实例成员属于对象
  • 静态方法中不能用this关键字,this表示当前对象,静态方法属于类,无对象

image-20220107121018850

代码块

使用{}括起来的代码称之为代码块,分为静态代码块和构造代码块:

  • 静态代码块(使用static修饰)
    格式:static{}
    特点:随类加载,自动触发,只加载一次
    场景:在类加载时做一些初始化操作,方便后续使用
  • 构造代码块(无修饰,不常用)
    格式:**{}**
    特点:每次创建对象时执行该代码,在构造器之前执行
    情景:初始化实力实例资源

静态代码块可用于初始化静态资源。

单例设计模式

利用static修饰符,可用来实现两种单例设计模式:饿汉模式懒汉模式,所谓单例模式是指保证系统中,使用单例模式的类只能创建一个对象。

饿汉单例模式

含义:在用类获取对象时,对象已经提前创建好。

实现:

  • 构造器私有化
  • 定义一个静态变量存储对象
1
2
3
4
5
6
7
8
9
10
/*
* 饿汉单例模式
* */
public class SingleInstance1 {
// 定义静态变量存储对象
public static SingleInstance1 instance = new SingleInstance1();
// 构造器私有化
private SingleInstance1() {
}
}

image-20220108191215069

懒汉单例模式

含义:需要对象时,才为其创建对象(延迟加载对象)。

实现:

  • 构造器私有化
  • 定义一个静态变量存储对象,并私有化
  • 提供一个返回单例对象的方法(getInstance)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
* 懒汉单例模式
* */
public class SingleInstance2 {
// 定义私有化静态变量存储对象,未调用先置空(输出为null)
private static SingleInstance2 instance;
// 定义返回单例对象的方法
public static SingleInstance2 getInstance(){
// 判断是否已经创建
if (instance == null){
instance = new SingleInstance2();
}
return instance;
}
// 构造器私有化
private SingleInstance2() {
}
}

image-20220108193819741

总结

饿汉单例模式方便,但是占用内存资源,可能调用有的类并不需要实例化对象,但是饿汉单例模式默认创建一个对象。

懒汉单例模式省资源,一般用的比较多。