static关键字是什么?
在Java中,定义了一个static关键字,它用于修饰类的成员,如成员变量、成员方法以及代码块等。 当一个成员被声明为静态时,它被称为类成员(或类属性),而不是实例成员。类成员在内存中只有一份拷贝,被所有的对象共享。可以通过类名直接访问, 无需创建类的实例。
一、共享性
定义一个类时,只是在描述某类事物的特征和行为,并没有产生具体的数据。只有通过new关键字创建了该类的实例对象之后,系统才会给每个对象分配内存空间来存储各自的数据。后来,人们想要某些特定的数据在内存中只有一份,而且能被一个类中所有的实例对象所共享,这样就可以大大地减少内存空间的使用,节省资源。
以静态变量为例:
public class Student {
static String schoolName;
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
Student.schoolName = "哔哩大学";
System.out.println("我是"+s1.schoolName+"的学生");
System.out.println("我是"+s2.schoolName+"的学生");
System.out.println("我是"+Student.schoolName+"的学生");
}
}
从中可以看出,schoolName是一个静态变量,可以直接使用Student.schoolName的方式调用,也可以通过Student的实例对象进行调用(s1、s2共享了schoolName)
一、静态变量
静态变量:使用static修饰的变量称为静态变量(或类变量),它们属于类而不是实例。
通过对象修改静态成员的值,会影响到其他所有对象对该静态成员的访问。
class MyClass {
static int staticVariable;//静态变量
int instanceVariable;//实例变量
public static void main(String[] args) {
MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();
obj1.staticVariable = 10;
System.out.println(obj2.staticVariable); // 输出 10
obj1.instanceVariable = 20;
System.out.println(obj2.instanceVariable); // 输出 0
obj2.instanceVariable = 30;
System.out.println(obj1.instanceVariable); //输出20
obj1.instanceVariable = 30; //输出30
System.out.println(obj1.instanceVariable);
}
}
第一条输出: staticVariable是一个静态变量,虽然是由obj1来引用来初始化为10,但是输出
obj2.staticVariable的值也是10,因此静态变量的值,无论是哪个对象引用值都是一样的。
第二条输出: obj2.instanceVariable是一个实例变量,并且没有被显式初始化。因此,它的默认值为0。
第三条输出 obj2.instanceVariable 初始化为30,但是输出obj1.instanceVariable的值为20,这个强调了实例化对象的值要看清到底是哪个对象在引用
第四条输出: obj1.instanceVariable 已经被初始化为30,所以输出30
二、静态方法
静态方法:使用static修饰的方法称为静态方法(或类方法),静态方法可以直接通过类名调用, 无需创建类的实例。值得注意的是:静态方法只能访问静态变量和调用其他静态方法,不能访问非静态的实例变量和实例方法。
第2行没有static修饰speak方法,idea直接报错。这说明静态方法只能调用其他静态方法,不能访问非静态的实例方法。 下面以一个正确的代码来举个例子:
class Person {
public static void speak() { //定义静态方法
System.out.println("Hello!");
}
}
public class Test {
public static void main(String[] args) {
Person.speak();//以“类名.方法”的方式调用了静态方法
Person p = new Person();
p.speak();//以“实例对象名.方法”的方式调用了静态方法
}
}
两者都成功地输出了"Hello!" 这也可以说明静态成员可以被所有实例化对象所共享。
三、静态代码块
静态代码块:使用static关键字定义的一段代码块, 它在类加载时执行,用于初始化静态变量或执行其他静态操作。静态代码块只会执行一次,且在类加载过程中的静态变量初始化之前执行。
静态代码块的语法如下:
static {
// 静态代码块中的代码
}
静态代码块是在类被加载时执行的,只会执行一次。而构造方法是在每次创建类的新对象时执行的。
具体来说:
- 静态代码块:静态代码块是随着类的加载而执行,只会执行一次。无论创建多少个对象,静态代码块都只执行一次。
- 构造方法:每次创建类的对象时,都会执行构造方法。如果你创建了10个对象,那么构造方法就会被调用10次。
需要注意的是,静态代码块和构造方法的执行顺序是:先静态代码块,后构造方法。如果存在多个静态代码块,那么这些静态代码块按照在代码中出现的顺序执行。同样地,如果存在多个构造方法,那么这些构造方法也是按照在代码中出现的顺序执行。
四、静态内部类
静态内部类:使用static修饰的内部类称为静态内部类。 静态内部类与外部类的实例无关,可以直接通过外部类名访问。
下面介绍一下静态内部类与普通内部类(非静态内部类)有一些区别和特点。
1、定义方式: 静态内部类的定义方式为在外部类内部使用static关键字修饰一个类。例如:
public class OuterClass {
// 外部类的成员和方法
public static class StaticInnerClass {
// 静态内部类的成员和方法
}
}
2、独立性: 静态内部类是外部类的静态成员,与外部类的实例无关。它可以独立存在,无需依赖外部类的实例。因此,可以直接通过外部类的类名访问静态内部类。
3、访问权限: 静态内部类可以具有公共、私有、受保护或默认(包级别)的访问权限,与普通类一样。它的访问权限不受外部类的访问权限限制。
4、访问外部类: 静态内部类可以直接访问外部类的静态成员,包括静态变量和静态方法。如果需要访问外部类的非静态成员,需要通过对象实例来访问。
5、实例化: 要实例化静态内部类,不需要外部类的实例。可以直接使用静态内部类的类名创建对象。例如:
OuterClass.StaticInnerClass inner = new OuterClass.StaticInnerClass();
6、生命周期: 静态内部类的生命周期与外部类相互独立。即使外部类的实例被销毁,静态内部类的对象仍然可以存在。
总而言之,静态内部类在某些情况下很有用,特别是当内部类不需要访问外部类的实例变量或方法时。它提供了一种组织和封装相关功能的方式,并且可以通过外部类的类名直接访问。
以上便是我对static关键字的讲解,希望能对大家有所帮助!!!