> 文档中心 > 一篇带你详解static关键字(超详细)

一篇带你详解static关键字(超详细)

在这里插入图片描述


文章目录

  • 前言
  • 一、static可以修饰哪些东西?
  • 二、static修饰属性
    • 1.为什么要引入static?
    • 2.final和static的区别
    • 3.修饰属性总结
  • 二、static修饰方法
    • 2.1为什么主方法是静态方法?
    • 2.2静态方法能否访问成员方法和成员属性
    • 2.3成员方法能否访问静态方法和静态属性
  • 三、static修饰代码块

前言

static关键字,一看见static关键字,就要本能的想到被static修饰的东西一定的对象无关,有的语言中也把static叫做静态,表示共有的含义


一、static可以修饰哪些东西?


二、static修饰属性

static修饰的属性称为类属性,类变量,所有对象共享

1.为什么要引入static?

public class StaticTest{Person per2 = new Person();per2.name = "小泉";per2.age = 50;Preson.country = "小日本";Person per1 = new Person();per1.name = "张三";per1.age = 18;Person.country = "中国";per1.show();per2.show();}class Person[String name;int age;static String country = "中国";void show(){System.out.println("姓名为:" + name + ",年龄为:" + age + ",国籍为:" + country)}]//输出结果//姓名为:张三,年龄为:18,国籍为:中国//姓名为:小泉,年龄为:50,国籍为:中国

1.看到上面的代码,我们会看到,per2这个对象的国籍输出本来应该为“小日本”,但是输出却为“中国”,这是怎么回事呢?这是因为country这属性是被“static”关键字修饰的属性,一个成员属性一旦被static修饰,他就表示类的属性,就会被存入JVM的方法区中,被该类的所有对象共享此属性,所有对象的属性值都一样;而且很多对象可能是同一个值,比如中国人的所有对象的country都是中国,如果不用static修饰,那么每个对象都在堆中保存自己的country属性,会占用很多的空间。
2.而且被static修饰的属性,被任意一个对象所修改之后,对于该类中所有的对象都是可见的,被其中一个对象修改了值,那么所有对象的此属性都为修改后的值(牵一发而动全身)。
3.static修饰的属性,直接通过类名称就可以访问,无需通过对象访问。
例如country被static修饰就可以直接通过Person访问
Person.country

内存图
调用new Person()来产生Person对象,首先要有Person这个类才能产生对象,首先要将Person类加载到内存中,Person类中的所有static变量就会被加载到方法区中
方法区中存放类中的所有方法,常量,静态变量
在这里插入图片描述

在Java中,在一个方法的内部是不能定义一个static变量的,因为方法中定义的变量全部都是局部变量,局部变量保存在栈中,而静态变量保存在方法区中,局部变量出了方法区就会被栈回收,而静态变量不会,所以局部变量前不能加static

2.final和static的区别

class Persong{//成员常量,在堆中存储final age = 10;//静态变量。在方法区中存储sattic String country = "中国"}

1.finnal修饰的属性不可以被改变,所以被赋值之后就是一个常量,但还是成员属性,在堆中存储
2.static修饰的属性,被称为静态变量,在方法区中存储,所有的Person的对象共享这个属性
3.一旦在类中定义了一个常量(定义时就要赋值或者在构造方法中赋值),那么类中的所有对象的这个属性值都是一样的,那我们就可以使用static和final共同修饰这个属性,把他放在方法区中,让该类的的所有对象共享此属性,这样比较节省空间
4.全局常量,就是用static final共同修饰,常量的命名规则:所有单词全部大写,多个单词使用下划线分隔

3.修饰属性总结

1.static变量称为类属性,在方法区中存储,该类的所有对象共享此属性
2,若在类中定义了常量(定义时赋值或在构造方法中赋值),一般使用static和final共同修饰,称为全局常量
3.要使用类属性,我们通常使用类名称.属性名称,不推荐使用对象调用类属性,不规范。

3.1不产生对象可以直接通过类名称调用static属性吗?—> 可以

public class StaticTest{Person per = null;//不产生对象也能直接通过类名称调用System.out.println(Person.country)//static属性称为类属性,没有对象也可以直接通过类名称调用(包括该类的null引用)System.out.println(per.country)}class Person[String name;int age;static String country = "中国";void show(){System.out.println("姓名为:" + name + ",年龄为:" + age + ",国籍为:" + country)}]//结果//中国//中国

NullPointerException —> 空指针异常,一定是使用了一个值为null的引用取访问了属性或者方法,这里指的一定是成员属性和成员方法,而和静态属性和静态方法无关


二、static修饰方法

static修饰方法称为类方法,工具方法,静态方法,通过类名称直接访问,没有对象也能访问

2.1为什么主方法是静态方法?

主方法就是一个被static修饰的方法

主方法是一个程序的入口,如果主方法是成员方法,那就得通过对象来调用,此时没有入口,就产生不了对象
程序从主方法开始执行,主方法要能调用起来,就得是静态方法,直接调用,无需产生对象

2.2静态方法能否访问成员方法和成员属性

我们缕一缕其中的逻辑,静态方法是没有对象就可以调用,而成员方法和成员属性必须要有对象才能调用,这就产生了矛盾,记住一条结论
结论:在静态方法中只能调用静态属性和静态方法,static家族之间可以互相调用,不能直接调用成员变量和成员方法,必须通过对象调用。

2.3成员方法能否访问静态方法和静态属性

成员方法必须通过对象来调用,能用成员方法说明已经产生了对象,静态方法和静态变量无需对象就能调用,更何况现在已经产生了对象
结论:在成员方法中既可以调用成员方法,也可以调用静态方法。


三、static修饰代码块

static修饰代码块称为静态代码块,在类加载时执行一次
在这里插入图片描述
主类中的静态块优先于主方法执行,JVM执行主方法,首先得加载主类,主类一加载,静态块就执行了
在这里插入图片描述