javase(2023/11/16)

本文详细解释了Java中的类变量、静态变量、静态方法的概念,强调了它们在内存布局和使用场景中的特点。还介绍了main方法的作用以及类加载、构造器、代码块和静态代码块的执行顺序。
摘要由CSDN通过智能技术生成

目录

1、类变量(静态变量/静态属性)

2、类方法 (静态方法)

 3、main方法进一步理解

4、代码块 


1、类变量(静态变量/静态属性)

内存布局

JDK7以上版本,静态域存储于定义类型的Class对象中,Class对象如同堆中其他对象一样,存在于GC堆中,之前在方法区
TODO:以后再看看?

 定义

  • 是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量。
  • 什么时候需要用类变量? 当我们需要让某个类的所有对象都共享一个变量时,就可以考虑使用类变量(静态变量):比如:定义学生类,统计所有学生共交多少钱。Student (name, staticfee)

语法

  • 访问修饰符  static  数据类型  变量名;
  • static  访问修饰符  数据类型  变量名;

类变量与实例变量(普通属性)区别: 

  • 类变量是该类的所有对象共享的,而实例变量是每个对象独享的。
  • 类变量可以通过类名(子类名也ok).类变量名或者对象名.类变量名来访问,实例变量不能通过类名.类变量名方式访问。【前提是满足访问修饰符的访问权限和范围】

 注意事项

  • 类变量是在类加载时就初始化了,也就是说,即使你没有创建对象,只要类加载了就可以使用类变量了。
  • 类变量的生命周期是随类的加载开始,随着类消亡而销毁
  • 只加载一次

实践:第二个输出100,red,那个white只加载一次,被对象c修改后就永久修改了,c1和其共享

2、类方法 (静态方法)

使用场景

  • 当方法中不涉及到任何和对象相关的成员,则可以将方法设计成静态方法,提高开发效率。比如:工具类中的方法utils
     

类方法和普通方法区别联系

  • 类方法和普通方法都是随着类的加载而加载,将结构信息存储在方法区∶
  • 类方法中无this的参数。普通方法中隐含着this的参数
  • 类方法可以通过类名(子类名也ok)调用,也可以通过对象名调用。普通方法和对象有关,需要通过对象名调用,
  • 类方法中不允许使用和对象有关的关键字,比如this和super。普通方法(成员方法)可以。
  • 类方法(静态方法)中只能访问静态变量或静态方法。普通成员方法,既可以访问非静态成员,也可以访问静态成员。
  • 小结:静态方法,只能访问静态的成员,非静态的方法,可以访问静态成员和非静态成员(必须遵守访问权限)
     

 3、main方法进一步理解

解释main方法的形式:public static void main(Stringl] args)

  • main方法是虚拟机调用
  • java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public
  • java虚拟机在执行main(方法时不必创建对象,所以该方法必须是static
  • 该方法接收String类型的数组参数,该数组中保存 执行java命令(对应javac、java那个java命令)时传递给所运行的类的参数,

在dos下可以     java 执行的程序 参数1参数2参数3

idea下可以

package zhh.chapter09.main_;

public class TestMain {
    public static void main(String[] args) {
        for (int i = 0; i < args.length; i++) {
            System.out.println(args[i]);
        }
    }
}

4、代码块 

代码化块又称为初始化块,属于类中的成员[即是类的一部分],类似于方法,将逻辑语句封装在方法体中,通过0包围起来。
但和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过对象或类显式调用,而是加载类时,或创建对象时隐式调用。

语法

//修饰符可写可不写,写的话只能static
    //最后的";"写不写都行
    (修饰符){
        代码
    };

好处和使用场景

  • 相当于另外一种形式的构造器(对构造器的补充机制),可以做初始化的操作
  • 场景:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的复用性

类什么时候被加载

  • 创建对象实例时(new)
  • 创建子类对象实例,父类也会被加载
  • 使用类的静态成员时(静态属性,静态方法)

 注意事项

  • static代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次
  • 普通的代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会调用一次。
  • 如果只是使用类的静态成员(没创建对象)时,普通代码块并不会执行。
  • 静态代码块只能直接调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员。
     
  • 在类加载时,静态代码块和属性初始化就执行完毕,因此是优先于构造器和普通代码块执行的 
  • 构造器的最前面其实隐含了super()和调用普通代码块,
class A {
    public A(){
        //super(隐藏)
        //普通代码块(隐藏)
        //正常构造器代码
    }
}

创建一个对象时,在一个类调用顺序

  1. 调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们定义的顺序调用)
  2. 调用普通代码块和普通属性的初始化(注意:普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块和多个普通属性初始化,则按定义顺序调用)
  3. 调用构造方法。

创建一个子类对象时(继承关系),他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:

  1. 类的态代码块和静态属性(优先级一样,按定义顺序执行)
  2. 类的态代码块和静态属性(优先级一样,按定义顺序执行)
  3. 类的通代码块和普通属性初始化(优先级一样,按定义顺序执行)
  4. 类的造方法
  5. 类的通代码块和普通属性初始化(优先级一样,按定义顺序执行)
  6. 类的造方法 
package zhh.chapter09.codeblock;

/**
 * 创建一个子类对象时,
 * 他们的静态代码块,静态属性初始化,
 * 普通代码块,普通属性初始化,构造方法
 * 的调用顺序如下:
 */


import com.sun.xml.internal.bind.v2.TODO;

public class CodeBlockSequence {
    public static void main(String[] args) {
        //老师说明
        //(1) 进行类的加载
        //1.1 先加载 父类 A02 1.2 再加载 B02
        //(2) 创建对象
        //2.1 从子类的构造器开始
        //new B02();//对象
        new B02();
    }
}

class A02 { //父类
    private static int n1 = getVal01();
    static {
        System.out.println("A02 的一个静态代码块..");//(2)
    }
    {
        System.out.println("A02 的第一个普通代码块..");//(5)
    }
    public int n3 = getVal02();//普通属性的初始化

    public static int getVal01() {
        System.out.println("getVal01");//(1)
        return 10;
    }
    public int getVal02() {
        System.out.println("getVal02");//(6)
        return 10;
    }
    public A02() {//构造器
        //隐藏
        //super()
        //普通代码和普通属性的初始化......
        System.out.println("A02 的构造器");//(7)
    }
}

class B02 extends A02 { //
    private static int n3 = getVal03();
    static {
        System.out.println("B02 的一个静态代码块..");//(4)
    }
    public int n5 = getVal04();
    {
        System.out.println("B02 的第一个普通代码块..");//(9)
    }

    public static int getVal03() {
        System.out.println("getVal03");//(3)
        return 10;
    }
    public int getVal04() {
        System.out.println("getVal04");//(8)
        return 10;
    }
    public B02() {//构造器
        //隐藏了
        //super()
        //普通代码块和普通属性的初始化...
        System.out.println("B02 的构造器");//(10)
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值