java的加载顺序_java中类的加载顺序

一、触发类加载的几种情况:

(1)、调用静态成员时,会加载静态成员真正所在的类及其父类。

通过子类调用父类的静态成员时,只会加载父类而不会加载子类。

(2)、第一次 new 对象的时候 加载(第二次再 new 同一个类时,不需再加载)。

(3)、加载子类会先加载父类。(覆盖父类方法时所抛出的异常不能超过父类定义的范围)

注:如果静态属性有 final 修饰时,则不会加载,当成常量使用。

例:public static final int a =123;

但是如果上面的等式右值改成表达式(且该表达式在编译时不能确定其值)时则会加载类。

例:public static final int a = math.PI

如果访问的是类的公开静态常量,那么如果编译器在编译的时候能确定这个常量的值,就不会被加载;

如果编译时不能确定其值的话,则运行时加载

package staticTest;

import java.util.Random;

public class A {

static{

System.out.println("A static block...");

}

public static void main(String[] args) {

//System.out.println(B.a);

System.out.println(B.b);

}

}

class B{

static{

System.out.println("B static block1...");

}

public static final int a=new Random().nextInt(10);

public static final int b=2;

static{

System.out.println("B static block 2...");

}

}

out put:

A static block...

2

所以,调用某类的静态常量时,此类不会加载,但若表达式右边需要计算,则此类会加载。

二、类加载的顺序:

1、先递归地加载父类的静态成员/代码块(Object的最先),再依次加载到本类的静态成员。其中同一个类中的静态成员和静态代码块按编写代码的顺序加载。同一个类中调用方法时,不用理会写代码的顺序。

2、递归加载完父类至本类的静态成员或代码块后,再一次递归加载非静态成员、代码块和构造函数,这三者是一次性递归加载。其中同一个类中的非静态成员、代码块按编写顺序加载,均在构造函数之前加载。

package extendsTest;

public class staticTest{

public static int getInt(int i){

System.out.println(i);

return i;

}

public static void main(String[] args) {

new SmallOrange();

}

}

class Fruits {

private int a=staticTest.getInt(1);

static int a1=staticTest.getInt(11);

static{

System.out.println("Fruits()static");

}

{

System.out.println("Fruitsblock");

}

public Fruits(){

System.out.println("Fruits()constructor");

}

}

class Orange extends Fruits{

{

System.out.println("Orangeblock");

}

static{

System.out.println("Orange()static");

}

static int b1=staticTest.getInt(22);

public Orange(){

System.out.println("Orange()constructor");

}

private int b=staticTest.getInt(2);

}

class SmallOrange extends Orange{

private int c=staticTest.getInt(3);

static int c2=staticTest.getInt(33);

{

System.out.println("SmallOrangeblock");

}

static{

System.out.println("SmallOrange()static");

}

public SmallOrange(){

System.out.println("SmallOrange()constructor");

}

}

//output:

11

Fruits() static

Orange() static

22

33

SmallOrange() static

1

Fruits block

Fruits() constructor

Orange block

2

Orange() constructor

3

SmallOrange block

SmallOrange() constructor

由此我们可以看出,先递归完静态成员或静态块的加载,再递归非静态成员、非静态块、构造函数。其中构造函数再三者中是最后的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值