一、 什么是static?
static可以修饰成员变量、方法和初始化块,被static修饰的成员变量叫静态变量也叫类变量,被static修饰的方法叫静态方法(构造器是一种特殊的静态方法),被static修饰的初始化块叫静态初始化块,下面将逐一讲解这三者的区别。
二、 静态变量(类变量)
被static修饰的变量叫静态变量,他属于这个类本身而不属于该类的单个实例。也就是说他的作用域是整个类,并且可以被类调用也可以被对象调用,但是使用对象调用时Java虚拟机会隐式地修改成用类调用,为了不混淆概念,推荐使用类来调用更加符合实际含义。因为静态变量的作用域是整个类,所以他的生命周期是与类共存亡的。从类的加载初始化开始,他是第一个被分配了内存空间,并指定默认值一直存在,直到这个类被回收。
类变量用于那些固有信息或者需要被整个类的成员公用的属性,如人的眼睛是两只,则可以将eyes的值设置成2,或者需要给每个员工赋予唯一的标识码,每次新建一个员工对象标识码就加1。
下面代码将展示这个效果:
class Employee
{
Private static int nextId = 1;
Private int id;
public void setId()
{
Id = nextId;
nextId++;
}
}
上面的setId方法很好的利用的静态变量的特点,对员工进行id设置,每设置完一次id自动加1,然后赋值给对象的id成员变量,有点类似程序的计数器。
三、 静态方法
被static修饰的方法就叫静态方法,其实我们一直写的main方法就是静态方法。顾名思义静态方法就是一种不能向对象实施操作的方法,就像被施了禁锢魔法一样,它只能访问自身类中的类变量(静态变量)和方法,不能直接调用非静态变量(成员变量)。静态方法可以使用类来调用也可以使用对象来调用,不过很容易造成混淆,建议使用类来调用。在普通成员方法中,不用创建对象就可以直接访问同类的静态方法,像是一个固定的抽纸盒,随取随用。但是调用普通方法就不行,必须要创建一个对象才能调用普通方法。
下面是使用这种静态方法的一个示例:
public static int getNextId()
{
return nextId; //返回类变量
}
//通过以下类名调用这个方法
int n = Employee.getNextId();
一个方法不需要访问对象的状态,其所需参数都是通过显示参数提供(例如:Math.pow())
一个方法只需要访问类的静态域(例如:Employee.getNextId)
1. 静态方法可以访问静态变量,但不能访问非静态变量(可以通过创建类的对象来访问)
2. 静态方法可以调用静态方法,但不能调用非静态方法(可以通过创建类的对象来调用)
3. 非静态方法,既可以访问静态变量也可以访问非静态变量(访问静态方法推荐用类名)
4. 非静态方法,即可以访问静态方法也可以访问非静态方法(访问静态方法推荐用类名)
三、静态初始代码块
Java 中可以通过初始化块进行数据赋值。它总是先于构造器执行,相当于构造器的内容补充如:
public class PersonInfo
{
static location;
String name;
int age;
{
location = "中国";
}
public PersonInfo(String name,int age){
this.name = name
this.age = age;
}
}
在类的声明中,可以包含多个初始化块,当创建类的实例时,就会依次执行这些代码块。如果使用 static 修饰初始化块,就称为静态初始化块。静态初始化代码块只在类的加载时执行且只会执行一次,同时静态初始化块只能给静态变量赋值,不能初始化普通的成员变量。
先看下面这段代码:
public class Hello{
int num1;
int num2;
static int num3;
//构造器
public Hello(){
num1 = 1;
System.out.println("通过构造方法为变量num1赋值");
}
//初始化块
{
num2 = 2;
System.out.println("通过初始化块为变量num2赋值");
}
//静态初始化块
static {
num3 = 3;
System.out.println("通过静态初始化块为变量num3赋值");
}
public static void main(String[] args){
Hello h = new Hello(); //创建类的对象h
System.out.println("num1的值为:"+h.num1);
System.out.println("num2的值为:"+h.num2);
System.out.println("num3的值为:"+Hello.num3);
Hello h1 = new Hello(); //再次创建类的对象h2
}
}
输出结果如下:
通过静态初始化块为变量num3赋值
通过初始化块为变量num2赋值
通过构造方法为变量num1赋值
num1的值为:1
num2的值为:2
num3的值为:3
通过初始化块为变量num2赋值
通过构造方法为变量num1赋值
通过输出结果,我们可以看到,程序运行时静态初始化块最先被执行,然后执行普通初始化块,最后才执行构造方法。由于静态初始化块是类相关的 ,用于对整个类进行初始化处理,所以静态初始化块只在类加载时执行一次,当再次创建对象 h2 时并未执行静态初始化块。同样的,静态初始化块不能对非静态的一切进行访问,它只能访问静态变量。同时也不能被调用,因为它是个块。
大总结:
静态不能访问非静态(除非通过对象调用),非静态既可以访问静态也可以访问非静态。
最后觉得这篇文章对你有帮助,记得点个赞鼓励一下作者哦~