static 关键字,用于修饰成员变量和成员方法,被修饰的成员属于类,而不是单单属于某个实例对象。也就是说,既然属于类,那么不创建实例对象也可以调用了。
◆ 静态变量
静态变量,也叫类变量,即在书写上等同于被 static 关键字修饰的成员变量。
类的所有对象都共享同一个类变量的数据,任何对象都可以更改所在类的类变量的值,也可以在不创建该类的对象的情况下对类变量执行访问或修改操作。
1. 语法格式
<权限修饰符> static <数据类型> <变量名称>;
// eg:
static String classroom;
- 权限修饰符非必要,无修饰符等同于 default
2. 源码示例
以学生为例,每个学生都是独立的个体,但会有很多学生属于同一个教室,因此以教室编号作为其静态变量。
public class Student {
/**
* 成员变量
*/
private String name;
/**
* 静态变量
*
* 多个对象共享同一份数据
*/
public static String classroom;
public Student(){
System.out.println("无参构造方法...");
};
public Student(String name){
System.out.println("全参构造方法...");
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static String getClassroom() {
return classroom;
}
public static void setClassroom(String classroom) {
Student.classroom = classroom;
}
}
◆ 静态方法
静态方法,也叫类方法,在书写上等同于被 static 关键字修饰的成员方法。
1. 语法格式
<修饰符> static <返回值类型> <方法名称> (<参数列表>){
[方法体]
}
// eg:
public static String getClassroom() {
return classroom;
}
public static void setClassroom(String classroom) {
Student.classroom = classroom;
}
-
类方法可以直接访问类变量和类方法,包括它本身
-
类方法不可以直接访问普通成员变量或成员方法,但成员方法可以直接访问类变量或静态方法,因为内存中会先行加载并调用静态的内容,而后非静态的内容才会产生
-
静态方法中,不能使用 this 关键字,因为 this 指针代表当前对象,其本质上也是非静态的内容
2. 源码示例
/**
* 成员方法
*/
public void show(){
System.out.println("成员方法...");
// 成员方法可以访问成员变量
System.out.println(name);
// 成员方法可以访问静态变量
System.out.println(classroom);
}
/**
* 静态方法
*/
public static void location(){
System.out.println("静态方法...");
System.out.println(classroom);
// 不能直接访问非静态变量
// System.out.println(name);
// 不能使用this关键字
// System.out.println(this);
}
◆ 静态代码块
静态代码块,即定义在成员同层级位置上,以 static 关键字修饰的代码块。
系统启动时,其随着类的加载而执行且仅执行一次,优先于包括 main 方法和构造方法在内的所有方法的执行。
1. 语法格式
static {
[执行语句]
}
- 一般用于给类变量赋初始值
2. 源码示例
/*
* 静态代码块
*
* 类第一次使用时,静态代码块执行,且仅执行唯一的一次
* 另外,静态代码块总是优先于非静态执行,所以,静态代码块比构造方法先执行
*
* 一般用于一次性的对静态成员变量进行赋值
*/
static {
System.out.println("静态代码块执行...");
classroom = "201";
}
◆ 测试用例
static 修饰的内容都是随着类的加载而加载的,并且仅加载一次。在内存中存在一块被我们称为静态区的固定区域,用于专门存储静态内容,所以,其可以直接被类名调用,又因为它有限与对象存在,所以,可以该类的所有对象共享。
1. 语法格式
// 访问类变量
[类名称].[类变量名];
[对象名称].[类变量名];
// 调用静态方法
[类名].[静态方法名(参数列表)];
[对象名称].[静态方法名(参数列表)];
// eg:
Student.classroom;
Student.location();
- 多个对象均属于一个类,共享使用同一个静态内容,因此可以通过对象名访问静态成员,但是不建议这样,不仅语义上不通顺,而且会出现警告信息
2. 源码示例
import org.junit.Assert;
import org.junit.Test;
public class StudentTest {
@Test
public void testBlock() {
// 静态代码块代码会在类使用之前执行
System.out.println(Student.classroom);
Assert.assertEquals("201", Student.classroom);
}
@Test
public void testVariable() {
// 可以通过对象访问类变量
Student joyce = new Student("Joyce");
Assert.assertEquals("Joyce", joyce.getName());
Assert.assertEquals("201", joyce.classroom);
joyce.classroom = "205";
// 建议通过类名称进行访问,而非对象名称
Assert.assertEquals("205", Student.classroom);
}
@Test
public void testMethod() {
// 可以通过对象调用类方法
Student joyce = new Student("Joyce");
Assert.assertEquals("Joyce", joyce.getName());
joyce.setClassroom("203");
Assert.assertEquals("203", joyce.getClassroom());
// 建议通过类名称进行调用,而非对象名称
Student.setClassroom("203");
Student.location();
}
}
测试用例全部通过,并打印如下信息:
// testBlock
静态代码块执行...
201
// testVariable
全参构造方法...
// testMethod
全参构造方法...
静态方法...
203
◆ 应用场景
static 关键字,可以修饰变量、方法和代码块。在使用的过程中,主要应用还是想在不创建对象的情况下调用方法,我们一般将提供大量静态方法的类称为工具类。
以一个猜数的游戏为例,简单介绍下工具类的强大:
- 生成一个随机数
- 10次猜数机会,每次会获得一个反馈
- 猜对或者机会完全消耗则游戏结束
@Test
public void testGuess() {
double random = Math.random() * 100;
long actual = Math.round(random);
boolean isSuccess = false;
for (int i = 0; i < 10; i++) {
Scanner scanner = new Scanner(System.in);
int expected = scanner.nextInt();
if (expected > actual){
System.out.println("Too bigger!");
}else if (expected < actual){
System.out.println("Too Smaller!");
}else {
isSuccess = true;
System.out.println("Success!");
break;
}
}
if (!isSuccess){
System.out.println("Game over!");
}
}
java.lang.Math是一个数学相关的工具类,random()可以获取一个[0.1.0] 之间的伪随机数,round()可以获取最接近浮点数的整数,相当于四舍五入java.util.Scanner是一个扫描器,我们可以通过它,获取从键盘录入的数据
520

被折叠的 条评论
为什么被折叠?



