static关键字修饰下的静态变量和静态方法+单例模式

1.静态变量

首先静态变量与静态方法都保存在方法区中

静态变量: 使用static关键字定义的变量。static可以修饰变量和方法,也有static静态代码块。被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。

区别:

     | 成员变量    | 局部变量         | 静态变量     
---- | ------- | ------------ | --------- 
定义位置 | 在类中,方法外 | 方法中,或者方法的形参  | 在类中,方法外  
初始化值 | 有默认初始化值 | 无,需定义赋值后才能使用 | 有默认初始化值  
调用方式 | 对象调用    | 方法中调用        | 对象调用,类名调用
存储位置 | 堆中      | 栈中           | 方法区      
生命周期 | 与对象共存亡  | 与方法共存亡       | 与类共存亡    
别名   | 实例变量    | —            | 类变量      

对于静态变量来说类名.[静态变量名]调用,不能通过this.[静态变量名]调用.

2.静态块 :

1
2
	static{       //	专门初始化静态变量
}

3. 静态方法:被static修饰的方法

  • 静态方法中没有this引用
  • 静态方法只能访问静态变量

    静态不能引用非静态这一特性,是由于静态的会随着类的定义而被分配和装载入内存中这一关键点决定的;如果静态引用了非静态的,根本无法从内存中找到非静态的代码段

4. 类的初始化顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class aprint {
public aprint() {
System.out.println("成员变量初始化");
}
}

class bprint {
public bprint() {
System.out.println("静态变量初始化");
}

}

class People {

private aprint a = new aprint();
private static bprint b = new bprint();

static {

System.out.println("静态块");
}
{
System.out.println("实例块");
}

public People() {

System.out.println("构造方法");

}

public static void main(String[] args) {
People man = new People();
}
}

在这里插入图片描述

5.单例模式

一个类有且仅有一个实例,并且自行实例化向整个系统提供。
前提要保证构造方法私有
保证构造方法私有的原因:
确保不能在外面通过new对象,只能在类的内部实例化一个累的对象,然后调用这个对象.

加载快慢指的是加载先后问题

  1. 慢加载(在静态方法中new一个实例)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public People {  
    private static People p ;
    private People(){
    }
    public static People getIstance(){
    if(p == null )
    People p =new People() ;
    return p ;
    }
    }
  1. 快加载(直接通过静态变量new一个实例)
    1
    2
    3
    4
    5
    6
    7
    8
    public People {    //快加载
    private static People p =new People();
    private People(){
    }
    public static People getIstance(){
    return p ;
    }
    }
  1. 线程安全单例模式
    以后再写