- 修饰成员变量,使其成为类变量,也叫静态变量
- 修饰成员方法,使其成为类方法
- 修饰内部类,使其成为静态内部类
- 静态代码块
- 静态导包
修饰成员变量
被static关键字修饰的属性叫做静态属性,也叫类属性。顾名思义现在该属性为该类所有,而非该类实例化的对象所有,在类的加载阶段进行初始化。虽然使用类实例化的对象也能够调用该属性,但是该属性是属于类所有,所有该类的实例化对象和该类共享一个值,即操作的是同一个值。
public class Person{
static int age;
static int high = 175;
public static void main(String[] args){
System.out.println(age);
System.out.println(high);
}
}
class PersonTest{
public static void main(String[] args){
System.out.println(Person.age);
}
}
成员变量不给初始值的话,会进行默认初始化。
被static修饰的属性,可以认为是属于类的,只要类进行加载以后,便可以使用类名.属性名进行调用。
修饰成员方法
被static关键字修饰的方法叫做类方法,修饰后的方法可以直接使类名.方法名调用,减少了实例化对象进行调用的资源消耗。
简单的来说被static修饰的方法,可以认为是属于类的,只要类进行加载以后,则就可以进行使用。
public class Person{
static int age;
static int high = 175;
public static void seeMessage(String msg){
System.out.println(msg);
}
}
class PersonTest{
public static void main(String[] args){
Person.seeMessage("Hello Codermast!");
}
}
这里需要注意的是一个静态方法是不能够直接调用同类下的非静态方法,而非静态方法则可以调用同类下的静态方法。
修饰内部类
被static修饰的内部类完全独立于其所在的外部类,不属于外部类的对象,可以认为两个类是完全没有关系的两个类。
- 静态内部类可以包含静态成员,也可以包含非静态成员,但是在非静态内部类中不可以声明静态成员。
- 静态类内部不可以访问外部类的实例成员,只能访问外部类的类成员,即使是静态内部类的实例方法也不能访问外部类的实例成员,只能访问外部类的静态成员
- 外部类不可以定义为静态类,Java中静态类只有一种,那就是静态内部类,顶级类不能用static 修饰
外部类如何调用静态内部类的属性和方法:
外部类可以通过创建静态内部类实例的方法来调用静态内部类的非静态属性和方法
外部类可以直接通过“ 外部类.内部类.属性(方法)” 的方式直接调用静态内部类中的静态属性和方法
创建一个静态内部类实例:
在外部类中:直接使用类名创建即可,内部类名 name = new 内部类构造器
;
在其他类中:使用外部类.内部类 name = new 外部类.内部构造器
;
静态代码块
static修饰代码块的作用就是,在类加载以后进行执行这段代码。我们需要着重看一下具体的执行顺序。
class Dog {
String name;
public Dog(String name) {
this.name = name;
System.out.println("狗的名字叫:" + name);
}
}
class Person {
String name;
public Person(String name){
this.name = name;
System.out.println("人的名字叫:" + name);
}
static int age = 18;
static {
System.out.println("静态代码块1执行...");
}
static Dog xiaohuang = new Dog("小黄");
Dog xiaohua = new Dog("小花");
static {
System.out.println("静态代码块2执行...");
}
static int high = 175;
Dog xiaohei = new Dog("小黑");
static Dog xiaobai = new Dog("小白");
public static void main(String[] args) {
Person person = new Person("codermast");
}
}
该示例执行后的结果如下所示:
静态代码块1执行...
狗的名字叫:小黄
静态代码块2执行...
狗的名字叫:小白
狗的名字叫:小花
狗的名字叫:小黑
人的名字叫:codermast
则我们可以判断出执行的顺序为:
1、静态代码块和静态属性的顺序执行
2、非静态属性的执行
3、方法的调用
静态导包
静态导包用法,将类的方法直接导入到当前类中,从而直接使用“方法名”即可调用类方法,更加方便。
- PrintMsg类
public class PrintMsg{
public static void printMsg(String msg){
System.out.println(msg)
}
}
- Test类
import static codermast.util.PrintMsg.*;
public class Test{
public static void main(String[] args){
printMsg("hello codermast!")
}
}
注意:导入的静态方法所处的类,不能和调用的类在同一个包下。
static关键字的实际应用场景
-
常量声明:静态变量通常用于声明常量,这些常量在整个程序中的值都是不变的。例如,可以使用static关键字声明一个类的常量,如public static final int MAX_SIZE = 100;,这样的常量可以被类的所有实例访问。
-
工具类:静态方法通常用于创建工具类,这些类包含了一些通用的方法,可以在整个程序中被多个类直接调用。例如,Math类中的所有方法都是静态方法,可以直接通过类名调用,如Math.max(10, 20)。
-
单例模式:静态变量可以用于实现单例模式,即确保在程序的生命周期内只有一个类的实例存在。通过将类的构造方法设为私有,并在类中声明一个静态变量来存储实例,可以确保只有一个实例被创建,并且可以通过静态方法获取该实例。
-
静态内部类:静态关键字还可以用于声明静态内部类。静态内部类与普通内部类不同,它可以直接通过外部类的类名访问,并且不需要依赖于外部类的实例。静态内部类通常用于组织和封装相关的功能模块。
-
静态代码块:静态代码块在类加载时执行,并且只执行一次。它通常用于执行类的初始化操作,如加载驱动程序、初始化静态变量等。静态代码块可以保证在程序运行之前,静态变量已经被正确初始化。
常问题
1、"static"关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?
- “static”关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。
- Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。
2、是否可以在static环境中访问非static变量?
static变量在Java中是属于类的,它在所有的实例中的值是一样的。当类被Java虚拟机载入的时候,会对static变量进行初始化。如果你的代码尝试不用实例来访问非static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。
3、static静态方法能不能引用非静态资源?
不能,new的时候才会产生的东西,对于初始化后就存在的静态资源来说,根本不认识它。
4、static静态方法里面能不能引用静态资源?
可以,因为都是类初始化的时候加载的,大家相互都认识。
5、非静态方法里面能不能引用静态资源?
可以,非静态方法就是实例方法,那是new之后才产生的,那么属于类的内容它都认识。
6、java静态变量、代码块、和静态方法的执行顺序是什么?
基本上代码块分为三种:Static静态代码块、构造代码块、普通代码块
代码块
执行顺序:静态代码块——> 构造代码块 ——> 构造函数——> 普通代码块
继承中代码块
执行顺序:父类静态块——>子类静态块——>父类代码块——>父类构造器——>子类代码块——>子类构造器