静态 java 加载_Java 静态、类加载

1.静态是什么?有什么用?

static的主要作用在于创建独立于具体对象的域变量或者方法。

静态代码在程序运行之前,即编译阶段,分配内存。

每创建一个对象,都会在堆里开辟内存,存成员(属性),但是不存方法,方法是共用的,没必要每一个对象都浪费内存去存方法。有一个叫方法区的地方存方法。方法区里又有静态域,存静态变量或者静态方法。

普通变量和方法的调用:通过对象调用

静态变量和方法的调用:通过对象或类调用

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classMyTest8 {public static voidmain(String[] args) {

System.out.println(Plant.name);//通过类调用

Plant p1=newPlant();

System.out.println(p1.name);//通过对象调用

p1.name="植物";//类似方法,是公用的,改了之后就是改了,新建对象也是这个值

Plant p2=newPlant();

System.out.println(p2.name);//通过对象调用

}

}classPlant{static String name="静态植物";public static voidsay() {

System.out.println("植物类");

}

}/**输出

静态植物

静态植物

植物*/

静态的调用

在类被加载的时候,静态的代码都会被加载,并且只加载一次,放在方法区里,该类的对象一起用。省时省力。

2.加载类有什么用?

任何程序都要先加载到内存中才能和CPU进行交流,而JVM中的ClassLoader(类加载器)就是负责提前将,class文件加载到内存中去的。

3.类何时被加载?(普通人的宏观理解)

实例化对象时,如Chinese c1=new Chinese();此时加载了Chinese类

通过类名调用静态变量或静态方法的时候

如果实例化子类对象,会先加载父类

通过代码验证:

public classMyTest8 {public static voidmain(String[] args) {

Plant.say();//通过类名调用静态方法

Plant p1 = new Plant();//创建对象

Plant p2 = newPlant();

}

}classPlant{static String name="静态植物";public static voidsay() {

System.out.println("植物类");

}static{

System.out.println("植物类的静态代码被执行加载了");

}

{

System.out.println("植物类的普通代码被加载了");

}

}

输出:

植物类的静态代码被执行加载了

植物类

植物类的普通代码被加载了

植物类的普通代码被加载了

由此可知,Plant.say();调用方法时就加载了类,静态代码也都被执行了,并且只执行一次,创建对象的时候再次加载类,但是不执行静态代码,而是非静态代码。

再通过继承关系观察静态和非静态的关系

public classMyTest8 {public static voidmain(String[] args) {

Flower.say();//通过类名调用静态方法

Flower f1=new Flower();//创建花类对象

Flower f2=newFlower();

}

}classPlant{static String name="静态植物";public static voidsay() {

System.out.println("植物类");

}static{

System.out.println("植物类的静态代码被执行加载了");

}

{

System.out.println("植物类的普通代码被加载了");

}

}class Flower extendsPlant{static{

System.out.println("花类的普通代码被加载了");

}static String name="花";public static voidsay() {

System.out.println("花类");

}

{

System.out.println("花类的普通代码被加载了");

}

}

输出:

植物类的静态代码被执行加载了

花类的普通代码被加载了

花类

植物类的普通代码被加载了

花类的普通代码被加载了

植物类的普通代码被加载了

花类的普通代码被加载了

由此可知:调用静态的东西,只执行静态的代码,静态代码只执行一次。创建对象的时候也会加载,如果静态没有被加载过也会被加载,加载过就不用。加载子类的时候,会先把父类加载一次。

在代码中,调用子类静态方法,则先加载父类的静态代码,再加载子类的静态代码,再调用方法。创建对象的时候,先加载父类,再加载子类。

类装载的过程:

加载:根据查找路径找到相应的 class 文件然后导入;

检查:检查加载的 class 文件的正确性;

准备:给类中的静态变量分配内存空间;

解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,而在直接引用直接指向内存中的地址;

初始化:对静态变量和静态代码块执行初始化工作。

牛客刷题

1.初始化代码执行顺序是:

父类静态变量→父类静态代码块→子类静态变量→子类静态代码块→

父类普通变量→父类普通代码块→父类构造方法→

子类普通变量→子类普通代码块→子类构造方法

2.静态方法属于类不属于对象;静态方法中只能访问其他静态方法和静态数据,不能访问非静态的。

3.静态变量建议别用this调用

在语法上行得通,但是静态变量是所有实例共享的一个变量,而this通常指当前对象;用对象名调用普通变量,用类名调用静态变量更加直观。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值