一. static关键字的基本用法
1. static关键字基本概念
被static关键字修饰的不需要创建对象去调用,直接根据类名就可以去访问。
2. static关键字修饰类
static一般用来修饰成员变量或函数。但有一种特殊用法是用static修饰内部类,普通类是不允许声明为静态的,只有内部类才可以。
package com.yue.Static;
public class StaticClass {
// static关键字修饰内部类
public static class InnerClass {
InnerClass() {
System.out.println("============= 静态内部类=============");
}
public void InnerMethod() {
System.out.println("============= 静态内部方法=============");
}
}
public static void main(String[] args) {
// 直接通过StaticTest类名访问静态内部类InnerClass
InnerClass inner = new StaticClass.InnerClass();
// 静态内部类可以和普通类一样使用
inner.InnerMethod();
}
}
3. static关键字修饰方法
package com.yue.Static;
public class StaticMethod {
public static void test() {
System.out.println("============= 静态方法=============");
};
public static void main(String[] args) {
//方式一:直接通过类名
StaticMethod.test();
//方式二:
StaticMethod fdd=new StaticMethod();
fdd.test();
}
}
4. static关键字修饰变量
被static修饰的成员变量叫做静态变量,也叫做类变量,说明这个变量属于这个类,而不属于对象。
package com.yue.Static;
public class StaticVar {
private static String name = "StaticVar";
public static void main(String[] args) {
//直接通过类名
System.out.println(StaticVar.name);
}
}
5. static关键字修饰代码块
静态代码块在类第一次被载入时执行,类初始化的顺序:
- 父类静态变量
- 父类静态代码块
- 子类静态变量
- 子类静态代码块
- 父类普通变量
- 父类普通代码块
- 父类构造函数
- 子类普通变量
- 子类普通代码块
- 子类构造函数
父类:
```java package com.yue.Static.Example;
public class Father {
// 父类静态代码块
static {
System.out.println("Father static");
}
// 父类构造函数
public Father() {
System.out.println("Father constructor");
}
}
<a name="rYB6d"></a>
##### 子类:
```java
package com.yue.Static.Example;
public class Son extends Father {
// 静态代码块
static {
System.out.println("Son static");
}
// 构造方法
public Son() {
System.out.println("Son constructor");
}
public static void main(String[] args) {
new Son();
}
}
结果:
二. 深入分析static关键字
特点:
- static是一个修饰符,用于修饰成员。(成员变量,成员函数)static修饰的成员变量 称之为静态变量或类变量。
- static修饰的成员被所有的对象共享。
- static优先于对象存在,因为static的成员随着类的加载就已经存在。
- static修饰的成员多了一种调用方式,可以直接被类名所调用,(类名.静态成员)。
static修饰的数据是共享数据,对象中的存储的是特有的数据。
成员变量和静态变量的区别:
生命周期的不同:
- 成员变量随着对象的创建而存在随着对象的回收而释放。
- 静态变量随着类的加载而存在随着类的消失而消失。
- 调用方式不同:
- 成员变量只能被对象调用。
- 静态变量可以被对象调用,也可以用类名调用。(推荐用类名调用)
- 别名不同:
- 成员变量也称为实例变量。
- 静态变量称为类变量。
数据存储位置不同:
静态方法只能访问静态成员。(非静态既可以访问静态,又可以访问非静态)
- 静态方法中不可以使用this或者super关键字。
- 主函数是静态的。
三. 面试题
1.下列代码输出什么结果?
package com.yue.Static;
public class StaticTest {
static {
_i = 20;
}
public static int _i = 10;
public static void main(String[] args) {
System.out.println(_i);
}
}
答案:
解析:
理解所需的前置条件:
条件一:静态变量如何初始化
答案:直接赋值/用代码块/静态函数返回值
static {
_i = 10;
}
public static int _i;
等价于public static int _i = 10;
条件二:JDK如何处理static块
答案:根据先后顺序
public static int _i;
static {
_i = 10;
}
public static void main(String[] args) {
}
static {
_i = 20;
}
等价于
public static int _i;
public static void main(String[] args) {
}
static {
_i = 10;
_i = 20;
}
根据条件一得出:
static {
_i = 10;
}
public static int _i;
等价于
public static int _i = 10;
根据条件二得出:
static {
_i = 20;
}
public static int _i = 10;
等价于
static {
_i = 20;
_i = 10;
}
public static int _i;
最终得出:
_i = 10;
2. 为什么static的变量是唯一的,怎么实现的?
答案:
static声明的类存在方法区,而不是堆。
static声明变量/方法/类的不生成对象副本。