java基础 - static关键字的使用

static静态关键字

1、 什么是static?

static:静态,相对静止的状态。

2、为什么用static?

在一个类中,创建的对象都有的属性,这个属性是大家(所有的创建出来的对象)共享的。也是为了方便大家的使用,以及减少内存的消耗。

3、 什么时候用static?

工具类,记录某个方法调用的次数,声明内部类

4、 static关键字的使用

由static关键字修饰的是与类有关系,可以直接通过"类名.XXX"这种方式去访问。
如果是变量和方法被static修饰的话则称之为静态变量,静态方法

静态变量的测试:

  • 测试1: 使用“对象.静态属性"去访问静态变量的数值
  • 测试2: 使用"类名.静态属性"去访问静态变量的数值
  • 测试3: 使用新创建的对象去访问一个没有赋值的静态变量 (结果是null,没有出现空指针异常)
  • 测试4: 其中一个对象修改静态变量后,其它的对象访问的是?(修改后的静态变量)
  • 测试5: 将静态变量置一个空的字符串数值。使用类名.静态属性去访问.看结果是
  • 测试6: 使用空引用去访问静态变量,看是否会出现空指针异常?(不会)
    代码如下:
public class StaticTest {
    public static void main(String[] args) {
        Person person = new Person();
        person.name = "zebra";
        person.age = 24;	
        person.sex = "男";
        System.out.println(person);
        // 测试1
		System.out.println(person.nation);
		// 测试2
		System.out.println(Person.nation);
		// 测试3
        System.out.println(person.live);  // null
        // 测试4
		person.nation = "CNINA";
        System.out.println(Person.nation); // CHINA
		System.out.println(Person.nation); //CHINA
		// 测试5
		person.nation = "";
		System.out.println(Person.nation);
		System.out.println("空的数值赋值给静态变量:" + Person.nation);
		// 测试6
        person = null;
		System.out.println(person.nation);
		System.out.println(Person.nation);	
    }
}


class Person{
	// 成员变量: 实例变量、静态变量
    String name;
    int age;
    String sex;   // 实例变量
    static String nation = "CHN" ; // 静态变量	
	static String live;

    public Person() {

    }

    public Person(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
}

结果图如下:
在这里插入图片描述

静态方法的测试:

  • 测试1 类名.静态方法
  • 测试2 对象.静态方法
  • 测试3 空引用调用静态方法
public class StaticTest01 {
    public static void main(String[] args) {
        Person person = new Person();
        person.name = "zebra";
        person.age = 24;	
        //测试1 类名.静态方法
		Person.show();
        //测试2 对象.静态方法
	    person.show();	
        //测试3 空引用调用静态方法
		person = null;
		person.show();
}

	
class Person{
    String name;
    int age;
    public Person() {

    }
	
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
	
    public static void show(){
        System.out.println("Test Static Method");
    }
}

注意:
1、静态变量的存储位置,在JDK1.6时在方法区,之后的版本是在堆里面(此处是JDK1.6)
2、静态变量存储在方法区,在类加载的时候,进行初始化,不需要娶new对象,此时内存空间已经开辟出来了

5、静态代码块

5.1 什么是静态代码块?

static {
    语句块1;
    语句块2;
}

5.2 为什么要使用静态代码块?

要添加一些日志信息,

5.3 什么时候使用静态代码块?

在类加载的时候使用静态代码块,并且类加载只执行了一次。

5.4 静态代码块的简单使用

public class StaticTest02 {
	static {
	   System.out.println("A");
	}
	
    public static void main(String[] args) {
		
		Person.show();
		
	}
	
	static {
	       System.out.println("C");
	}
}

	
class Person{
    String name;
    int age;
    public Person() {

    }
	
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
	
    public static void show(){
        System.out.println("Test Static Method");
    }
}

测试结果如下:
在这里插入图片描述

5.4 静态代码块的常见笔试题

5.4.1 静态代码块、普通代码块,构造器的执行顺序
public class StaticBlockTest03 {
    public static void main(String[] args) {
        Tiger tiger = new Tiger("虎吼");
        System.out.println(tiger);
    }
}

class Animal{
    // 名称
    String name;
    // 性别
    String sex;
    // 年龄
    int age;

    static{
        System.out.println("父类的静态代码块执行了");
    }

    {
        System.out.println("父类的普通代码块执行了");
    }

    public Animal() {
        System.out.println("父类的无参构方法执行了");
    }

    public Animal(String name, String sex, int age) {
        System.out.println("父类的带参数构造方法执行了");
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

}


class Tiger extends Animal{
    // 声音
     String voice;

    static{
        System.out.println("子类的静态代码块执行了");
    }

    {
        System.out.println("子类的普通代码块执行了");
    }

    public Tiger() {
        System.out.println("子类的无参构方法执行了");
    }

    public Tiger(String voice) {
        System.out.println("子类的带参构方法执行了");
        this.voice = voice;
    }
}

结果如下图所示:
在这里插入图片描述

1、静态代码块的执行是在类加载的时候执行的,类只加载一次,所以静态代码块只执行一次
2、普通的代码块是在对象创建之后执行的,每创建一个对象,就执行一次这个代码块
整个加载过程是这样的:
1. main函数调用Tiger tiger = new Tiger(“虎吼”);类加载器会去找到Tiger类以及Tiger类的所有的父类,所以此时会去加载父类的静态代码块,并打印父类的静态代码块执行了。然后去执行子类的静态代码块,并打印子类的静态代码块执行了
2. 类加载完之后,开始初始化, 然后会去执行这个子类带参数的构造器
3. 又因为所有的类的构造器都会默认调用父类的构造器(super()的原因)
4. 此时子类tiger构造器会去调用父类Animal此时无参的构造器,之后先去执行父类普通代码块,并打印父类普通代码块执行了然后执行父类无参构造方法,并打印父类无参构造方法执行了
5. 接着调用子类的带参数的构造器,之后调用子类的普通的代码块并打印子类的普通的代码块执行了,调用子类中带参的构造方法并打印子类中带参的构造方法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值