static关键字与代码块

static关键字与代码块

一、static关键字

static是一个用于声明程序结构的关键字,意为“静态的”,此关键字可以用于全局属性和全局方法,主要特点是可以避免对象实例化的限制,在没有实例化对象的时候直接进行此类结构的访问。

1、静态属性

在一个类中,主要的组成就是属性和方法,而每一个对象都分别拥有各自的属性内容(不同对象的属性保存在堆内存的不同地址中)。

如果想要类中的某个属性定义为公共属性(所有对象都可以使用的属性),则可以在声明属性前加上static关键字。

package edu.blog.test21.staticTest01;

class Chinese {
    //普通成员属性
    private String name;
    private int age;
    //静态成员属性
    static String country = "中华人民共和国";

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getInfo() {
        return "姓名:" + this.name + "、年龄:" + this.age + "、国家:" + this.country;
    }
}

public class TestDemo {
    public static void main(String[] args) {
        Chinese perA = new Chinese("lisi", 10);
        Chinese perB = new Chinese("wangwu", 10);

        System.out.println(perA.getInfo());
        System.out.println(perB.getInfo());

        perA.country = "伟大的中华人民共和国";
        System.out.println("--------------------------");

        System.out.println(perA.getInfo());
        System.out.println(perB.getInfo());
    }
}

/*
执行结果:
姓名:lisi、年龄:10、国家:中华人民共和国
姓名:wangwu、年龄:10、国家:中华人民共和国
--------------------------
姓名:lisi、年龄:10、国家:伟大的中华人民共和国
姓名:wangwu、年龄:10、国家:伟大的中华人民共和国
 */

本程序在Chinese类中定义了一个static类型的country属性,这样该属性就成为公共属性,该属性会保存在全局数据区中,所有的对象都可以获取到相同的对象内容,当有一个对象修改了static属性内容都会影响到此类的所有实例化对象,内存关系如下所示。

在这里插入图片描述

若country没有定义成static类型时,则每个实例化对象都会拥有此属性。

在这里插入图片描述

static描述的是全局属性,对于全局属性除了可以利用实例化对象调用外,最大的特点在于可以直接利用类名且没有实例化对象产生的情况下进行调用。

public class TestDemo {
    public static void main(String[] args) {
        System.out.println("直接访问static属性:" + Chinese.country);
        Chinese.country = "中国";

        Chinese chinese = new Chinese("lisi", 10);
        System.out.println(chinese.getInfo());

    }
}

/*
执行结果:
直接访问static属性:中华人民共和国
姓名:lisi、年龄:10、国家:中国
*/

小结:

  1. 使用static定义的属性不在中保存,而是保存在全局数据区
  2. 使用static定义的属性内容表示类属性,类属性可以由类名称直接调用(虽然可以通过实例化对象调用,但是并不提倡此类格式);
  3. static属性虽然定义在类中,但是其可以在没有实例化对象的时候进行调用(普通属性保存在堆内存中,static属性保存在全局数据区中)。

在编写程序代码过程中,首要选择还是普通属性,而是否需要用static定义静态属性则根据实际需求选择。

2、静态方法

static除了可以进行属性定义之外,也可以进行方法的定义,其效果同static定义成员属性类似,即都可以在没有实例化对象时通过类名直接调用,不再赘述。

接下来我们来说一说static关键字修饰的方法和属性的访问特点:

  1. 非静态的成员方法
    • 能访问静态的成员变量
    • 能访问非静态的成员变量
    • 能访问静态的成员方法
    • 能访问非静态的成员方法
  2. 静态的成员方法
    • 能访问静态的成员变量
    • 能访问静态的成员方法

总结成一句话就是:静态成员方法只能访问静态成员


二、代码块

代码块是在程序中使用“{}”定义起来的一段程序,而根据代码块声明位置以及声明关键字的不同,代码块可以分为:

  1. 普通代码块
  2. 构造代码块
  3. 静态代码块
  4. 同步代码块

1、普通代码块

普通代码块是定义在方法中的代码块,利用这类代码块可以解决代码在一个方法中过长导致出现重复变量定义的问题。

我们先来看一下一个例子。

package edu.blog.test21;

public class CodeBlockTestDemo01 {
    public static void main(String[] args) {
        if (true) {
            int x = 10;
            System.out.println("x:" + x);
        }

        int x = 100;
        System.out.println("x:" + x);
    }
}

/*
执行结果:
x:10
x:100
 */

我们在if语句中定义了一个变量x,由于“{}”的作用,所以该变量不会与外部的变量x产生影响。

如果我们将if语句删去,“{}”就成了一个普通代码块,这样也可以保证两个x变量不会相互影响,也就是说使用普通代码块可以将一个方法中的代码进行部分分割。

范例:定义普通代码块

package edu.blog.test21.block;

public class CodeBlockTestDemo02 {
    public static void main(String[] args) {
        {
            int x = 10;
            System.out.println("x:" + x);
        }

        int x = 100;
        System.out.println("x:" + x);
    }
}

/*
执行结果:
x:10
x:100
 */

2、构造代码块

将代码块定义在一个类中,这样就成为构造代码块,其主要的特点是在使用关键字new实例化对象进行调用。

范例:定义构造代码块

package edu.blog.test21.block;

class Person {
    public Person() {
        System.out.println("[构造器]Person类的构造器执行");
    }

    {
        System.out.println("[构造块]Person构造块执行");
    }
}

public class CodeBlockTestDemo03 {
    public static void main(String[] args) {
        new Person();
        System.out.println("-------------------------");
        new Person();
    }
}

/*
执行结果:
[构造块]Person构造块执行
[构造器]Person类的构造器执行
-------------------------
[构造块]Person构造块执行
[构造器]Person类的构造器执行
 */

通过程序的执行的结果我们发现,每一个实例化新的对象时都会调用构造块,并且构造快代码的执行优先于构造器的执行


3、静态代码块

静态代码块也是在类中定义的,如果一个构造代码块使用了static关键字进行定义的话,那么就表示静态代码块。

静态代码块又两种情况:

  1. 非主类中定义的静态代码块;
  2. 主类中定义的静态代码块。

范例:在非主类中定义的静态代码块

package edu.blog.test21.block;

class Person {
    public Person() {
        System.out.println("[构造器]Person类的构造器执行");
    }

    {
        System.out.println("[构造块]Person构造块执行");
    }

    static {
        System.out.println("[静态块]Person静态块执行");
    }
}

public class CodeBlockTestDemo03 {
    public static void main(String[] args) {
        new Person();
        System.out.println("-------------------------");
        new Person();
    }
}

/*
执行结果:
[静态块]Person静态块执行
[构造块]Person构造块执行
[构造器]Person类的构造器执行
-------------------------
[构造块]Person构造块执行
[构造器]Person类的构造器执行
 */

在本程序中实例化了多个Person类对象,可以发现静态代码块优先于构造代码块执行,并且不管实例化多少个对象,静态代码块中的代码只执行一次

Tips:利用静态代码块可以实现一些公共的初始化操作。

范例:在主类中定义的静态代码块

package edu.blog.test21.block;

class Person {
    public Person() {
        System.out.println("[构造器]Person类的构造器执行");
    }

    {
        System.out.println("[构造块]Person构造块执行");
    }

    static {
        System.out.println("[静态块]Person静态块执行");
    }
}

public class CodeBlockTestDemo03 {
    static {
        System.out.println("[静态块]主类中的静态块执行了");
        System.out.println("-------------------------");
    }

    public static void main(String[] args) {
        new Person();
        System.out.println("-------------------------");
        new Person();
    }
}

/*
执行结果:
[静态块]主类中的静态块执行了
-------------------------
[静态块]Person静态块执行
[构造块]Person构造块执行
[构造器]Person类的构造器执行
-------------------------
[构造块]Person构造块执行
[构造器]Person类的构造器执行
 */

通过程序的执行结果发现,主类中定义的静态代码块代码会优先于主方法执行


注:此文章为个人学习笔记,若有错误,敬请指正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

窝在角落里学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值