Java中static关键字的用法总结

一、 什么是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成员变量,有点类似程序的计数器。

  • 小总结:
  1. 静态变量的作用域是整个类,是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果。
  2. 如果静态变量没有指定初始值,Java会给类变量指定默认值(0、null或false)。
  3. 静态变量可以被类调用也可以被对象调用,但被对象调用会被认为是被类调用。鉴于他作用的特殊性更推荐用类名访问。
  4. 静态变量存储在方法区。
  5. 静态变量无法访问没有被非静态变量。

三、 静态方法

  被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 时并未执行静态初始化块。同样的,静态初始化块不能对非静态的一切进行访问,它只能访问静态变量。同时也不能被调用,因为它是个块。

大总结:
  静态不能访问非静态(除非通过对象调用),非静态既可以访问静态也可以访问非静态。

  最后觉得这篇文章对你有帮助,记得点个赞鼓励一下作者哦~

你可能感兴趣的:(Java中static关键字的用法总结)