特殊语法补充:static 关键字、局部代码块、局部代码块、静态代码块

目录

static 关键字

代码块

局部代码块(开发中不会用)

局部代码块

静态代码块


static 关键字

可以修饰 普通成员变量普通成员方法 (补充:严格来说static修饰的变量和方法属于类,不属于对象,只是习惯性称呼为静态成员变量和方法)

特点
1.被类的所有对象所共享:(判定是否使用static的关键)
    a.当static修饰了成员变量,该成员变量变量的值,就不在存储与对象中了,而是,单独存储了一份,被类的所有对象所共享
    b.当static修饰成员方法的时候,该方法被当前类的所有对象共享
        当前类对象.方法(和普通成员方法从共享的角度,几乎没有太大区别)

2.可以通过类名访问
    a.可以通过类名直接访问,static成员变量的值
    b.直接通过类名直接调用,static成员方法

3.随着类的加载而加载
    a. static成员变量,随着类加载过程,其实就已经在方法区中,分配了内存
    b. static成员方法,一旦类加载完毕,我们就可以直接访问,static方法,而不必等待,创建对象,然后在对象名访问方法

4.优先于对象而存在
    1.不依赖于对象而存在
        a.成员变量的角度来理解,static修饰的成员变量,不在依赖于对象而存在,因为static修饰的成员变量的值。不在存储在,该类的每个对象中
作为对比,没有被static修饰的成员变量,都依赖于对象而存在,因为他们的值,都存储在对象中
        b.成员方法角度,被static修饰的成员方法,在没有对象存在的情况下,也可以直接通过类名来调用方法作为对比,没有被static修饰的,普通的成员方法,它依赖于对象而存在,原因是,普通成员方法中,可以访问,普通成员变量的值,而普通对象的值又是依赖于对象而存在的

    2.先出现在内存(时间在先,主要是从static成员变量和没有被static修饰的普通成员变量的对比) 静态成员变量,一定 优先与 没有被static修饰的普通成员变量

注意事项:

a.非静态成员变量(非静态的成员方法),不能在静态上下文(静态方法的方法体)中被访问 为什么???

1)之所以静态方法的方法体中,不能访问非静态成员变量,因为静态方法,优先于对象而存在 首先,我们可以在没有任何对象存在情况下,就可以直接通过类名,运行静态方法,所以静态方法,是访问不到当前对象的普通成员变量值(因为此时,当前对象不存在)

2)之所以静态方法方法体中,不能访问非静态的成员方法,因为,如果静态方法可以直接调用非静态的方法,非静态的方法可以去访问当前对象的成员变量值,而当前对象此时有可能还不存在

b.静态方法 or 非静态方法,方法体中都不能使用static 关键字定义变量

c.静态方法的使用场景 静态方法和非静态方法除了访问方式不同, 最大的区别,就是静态方法可以访问到的数据集合和非静态的方法不同(静态方法方法体中,不能访问非静态的成员变量)所以通常,静态方法它所访问的数据:要么是静态的成员变量,要么是方法的形式参数

通常,定义静态方法,都是为了方别使用该方法的功能(工具方法,例如.toString()),让别人使用该方法的功能, 为了方便使用该方法,通常,将这种工具方法定义为静态方法(访问的数据通常是方法参数),不用创建对象就可以使用

public class StaticDemo {
    public static void main(String[] args) {
        StaticClass staticClass = new StaticClass();
        //1.被类的所有对象所共享
        //静态成员变量的值,被类的所有对象共享
        System.out.println(staticClass.staticField);//100
        //静态成员方法,被类的所有对象共享
        staticClass.testStatic();//testStatic

        //2.可以通过类名访问
        System.out.println(StaticClass.staticField);//100
        StaticClass.testStatic();
        //StaticClass.testMethod();错误,普通方法需要对象
    }
}

class StaticClass {
    //定义静态成员变量
    static int staticField = 100;

    double doubleValue = 9.9;

    //定义静态成员方法
    public static void testStatic() {
        System.out.println("testStatic");
    }

    public void testMethod() {
        System.out.println("testMethod");
    }
}

static 单独存储示意图---共享

 静态成员方法与普通成员方法图解

class StaticClass {
    //定义静态成员变量
    static int staticField = 100;

    double doubleValue = 9.9;

    //定义静态成员方法
    public static void testStatic() {
        System.out.println(staticField);
        test();
    }

    public static void test() {
    }

    public void testMethod() {
        //可以直接访问,静态成员方法和静态成员变量
        System.out.println(staticField);
        testStatic();
        test();
    }
}

静态成员变量和普通成员变量:

所属不同:静态变量属于类,所以也称为为类变量 成员变量属于对象,所以也称为实例变量(对象变量)

内存中的位置不同:静态变量存储于方法区的静态区 成员变量存储于堆内存

内存出现时间不同:静态变量随着类的加载而加载,随着类的消失而消失 成员变量随着对象的创建而存在,随着对象的消失而消失

调用不同:静态变量可以通过类名调用,也可以通过对象调用 成员变量只能通过对象名调用

静态上下文 不能访问非静态的成员变量或成员方法的补充

a.在静态方法中,不能访问的非静态的成员变量或成员方法(this的)

b.在静态方法中,对于非this的普通成员变量或成员方法可以访问

class StaticClass1 {
    int i;

    public static void test(StaticClass1 obj) {
        //在新创建的对象上访问普通成员变量或成员方法不会有问题
        StaticClass1 staticClass1 = new StaticClass1();
        System.out.println(staticClass1.i);//正确
        staticClass1.method();//正确
        //不能this,当前对象不存在
        this.i;//错误
        this.method();//错误
        //obj 是已经存在的对象
        System.out.println(obj.i);//正确
        obj.method();//正确
    }
    public void method() {
    }
}

代码块

1.在Java中,使用{ }括起来的代码被称为代码块

2.根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)

局部代码块(开发中不会用):

1.声明位置:定义在方法体中的用括起来的一段代码

2.执行时机:随着方法的执行而执行

优点:限定变最生命周期,及早释放,提高内存利用率

(这个优点理论上确实存在,但是这个优点,在现在jvm中其效果,微乎其微的,甚至可以忽略不计)我们在开发中,同时还要追求,代码可维护性(包括代码的可读性) 在嵌套的代码块中,不能定义同名变量

public static void main(String[] args) {
    testLocalBlock();
}
//局部代码块
public static void testLocalBlock() {
    //局部代码块:啥时执行呢?随着方法执行而执行
    {
        int i = 0;
        System.out.println(i);
    }
}
public class Demo1 {
    public static void main(String[] args) {
        //可以在住方法上创建一个对象,然后调用方法
        Demo1 demo1 = new Demo1();
        demo1.testLocalBlock();
    }
    //局部代码块
    //不加static
    public void testLocalBlock() {
        //局部代码块:啥时执行呢?随着方法执行而执行
        {
            int i = 0;
            System.out.println(i);
        }
    }
}

构造代码块:

1.声明的位置,类中,方法体之外{ }包含的代码

2.执行特征:创建对象的时候执行,而且每次创建对象的时候必执行 构造方法和构造代码块,都是在创建对象的时候执行,有没有先后顺序呢?构造代码块先执行,构造方法后执行

使用场景:

1.可以把多个构造方法方法中相同的,提取朱来放到构造代码块中,每次调用构造都执行,并且在构造方法前执

2.我们也可以用构造代码块来初始化对象的成员变量值

关于成员变量初始化语句,构造代码块中的赋值语句,以及构造方法中的赋值(都是对成员变量的赋值),有如下结论:

1.不管是成员变量的初始化语句,还是构造代码块中的赋值语句,它们都先于构造方法的赋值执行

2.初始化语句和构造代码块中的赋值语句,执行的先后顺序和代码书写顺序有关,谁在前谁就先执行

public class Demo2 {
    public static void main(String[] args) {
        CodeBlockClass codeBlockClass = new CodeBlockClass();
    }
}
class CodeBlockClass {
    int i;
    int j;
    {
        System.out.println("构造代码块1执行了");
    }
    public CodeBlockClass() {
        System.out.println("构造方法执行了");
    }
    {
        System.out.println("构造代码块2执行了");
    }
}
/*
构造代码块1执行了
构造代码块2执行了
构造方法执行了
*/
public class Demo2 {
    public static void main(String[] args) {
        CodeBlockClass codeBlockClass = new CodeBlockClass();
        CodeBlockClass codeBlockClass1 = new CodeBlockClass(1);
        CodeBlockClass codeBlockClass2 = new CodeBlockClass(1, 2);
    }
}
/*假设,我有这样一个功能要实现:我希望有一段代码,不管在创建对象时,用的是哪个构造方法,来初始化对象初值,我都希望这段代码一定执行*/
class CodeBlockClass {
    int i;
    int j;

    {
        System.out.println("构造代码块1执行了");
        this.i = 10;//初始化
        this.j = 20;//初始化
    }

    public CodeBlockClass() {
        System.out.println("无参构造方法执行了" + i + j);
    }

    public CodeBlockClass(int i) {
        this.i = i;
        System.out.println("一参构造方法执行了" + i);
    }

    public CodeBlockClass(int i, int j) {
        this.i = i;
        this.j = j;
        System.out.println("两参构造方法执行了" + i + j);
    }

    {
        System.out.println("构造代码块2执行了");
    }
}

/*
构造代码块1执行了
构造代码块2执行了
无参构造方法执行了1020
构造代码块1执行了
构造代码块2执行了
一参构造方法执行了1
构造代码块1执行了
构造代码块2执行了
两参构造方法执行了12
*/

静态代码块:

1.声明位置:类中方法体之外,除此之外,还被static关键字修饰 static { }

2.执行特征:静态代码块,随着类加载而执行,所以静态代码块至多执行一次

注意事项:静态上下文,多了个静态代码块

class CodeBlockClass{
    //static int staticInt = 100;  先执行
	static {
    	staticInt = 200;
    	System.out.println("静态代码块执行了");
    }
    //static int staticInt = 100;  后执行
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值