Java中代码块与代码加载顺序原理的示例分析-创新互联

这篇文章将为大家详细讲解有关Java中代码块与代码加载顺序原理的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

在莲池等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供网站设计、成都网站设计 网站设计制作定制开发,公司网站建设,企业网站建设,成都品牌网站建设,网络营销推广,成都外贸网站制作,莲池网站建设费用合理。

在面试大型公司时,如果遇到大型国企或者大的互联网私企,笔试中经常遇到代码块和代码加载顺序的笔试题。这里做一个总结,也方便各位小伙伴飙车不会飘。

名词解释

代码块

由 { } 包起来的代码,称为代码块

静态代码块

由 static { } 包起来的代码,称为静态代码块。

不同类型变量定义示例:

class Demo{
  String x;// 非静态成员变量,又称为属性,对该类不同的对象来说,属性互不相同
  static int y = 32;// 类变量,一个类中只有一个该变量,该类不同的对象共享同一个静态成员变量
  public static void main(String[] args){
    int z = 0;// 局部变量,只在方法内部可见,在方法结束后由垃圾收集器自动回收
  }
}

局部代码块

位置:局部位置(方法内部)。

作用:限定变量的生命周期,尽早释放,节约内存。

调用:调用其所在的方法时执行。

方法中的局部代码块一般进行一次性地调用,调用完立刻释放空间,避免在接下来的调用过程中占用栈空间。栈空间内存有限,方法调用可能会生成很多局部变量导致栈内存不足,使用局部代码块可以避免此缺陷。

public class 局部代码块 {

   public static void go() {
    // 局部代码块
    {
      int age = 30;
      System.out.print("go: " + age);
    }
  }
  public static void main(String[] args) {
    go();
  }
}

构造代码块

位置:类成员的位置,即类中方法之外的位置。

作用:把多个构造方法共同的部分提取出来,共用构造代码块。

调用:每次调用构造方法时,都会优先于构造方法执行,也就是每次new一个对象时自动调用,实现对象初始化。

public class A {
  int i = 1;
  int initValue;//成员变量,初始化交给代码块来完成
  A(){
    System.out.println("构造方法在代码块执行后运行");
  }
  {
    System.out.println("代码块从上至下依次运行");
    //代码块的作用体现于此:在调用构造方法之前,用某段代码对成员变量进行初始化。
    //而不是在构造方法调用时再进行。
    for (int i = 0;i < 100;i ++) {
      initValue += i;
    }
  }
  {
    System.out.println(initValue);
    System.out.println(i);//此时会打印1
    int i = 2;//局部变量,和成员变量不冲突,但会优先使用代码块的变量
    System.out.println(i);//此时打印2
    //System.out.println(j);//提示非法向后引用,因为此时j的的初始化还没开始。
  }
  int j = 2;
  {
    System.out.println(j);
    System.out.println(i);//代码块中的变量运行后自动释放,不会影响代码块之外的代码
  }

}
public class 构造代码块 {
  @Test
  public void test() {
    A a = new A();
  }
}

执行结果

代码块从上至下依次运行
1
2
构造方法在代码块执行后运行

静态代码块

位置:类成员位置。

作用:对类进行一些初始化,只加载一次。当new多个对象时,只有第一次会调用静态代码块,因为静态代码块和类变量一样,

是属于类的,所有对象共享一份。

调用: new 一个对象时自动调用。

public class 静态代码块 {
@Test
public void test() {
  C c1 = new C();
  C c2 = new C();
  //结果,静态代码块只会调用一次,类的所有对象共享该代码块
System.out.println("我是普通方法");
}
}
class C{
  C(){
    System.out.println("构造方法调用");
  }
  {
    System.out.println("代码块调用");
  }
  static {
    System.out.println("静态代码块调用");
  }
}

调用结果:

静态代码块调用
代码块调用
构造方法调用
代码块调用
构造方法调用
我是普通方法

执行顺序 静态代码块 —–> 构造代码块 ——-> 构造方法

笔试题

写出下列程序输出结果:

public class HelloA {
  public HelloA(){
    System.out.println("HelloA");
  }
  {
    System.out.println("I'm A class");
  }
  static {
    System.out.println("static A");
  }
}
public class HelloB extends HelloA {
  public HelloB(){
    System.out.println("HelloB");
  }
  {
    System.out.println("I'm B class");
  }
  static {
    System.out.println("static B");
  }
  public static void main(String[] args) {
    new HelloB();
  }
}

执行结果:

Java中代码块与代码加载顺序原理的示例分析

分析:首先要知道静态代码块是随着类的加载而加载,而构造代码块和构造方法都是随着对象的创建而加载。

1,在编译HelloB.java时,由于HelloB 继承 HelloA,先加载了HelloA类,因此HelloA类的静态代码块首先执行,而后加载HelloB类,HelloB类的静态代码块执行,这没什么好说的。

2,然后创建HelloB的对象,大家都知道构造代码块优先于构造方法执行,这时候问题来了,这时应该先看HelloB类的构造方法,HelloB类里的构造方法里有一句隐式的super()首先被执行,所以找到HelloA类的构造方法,而HelloA类的构造方法中也有一句隐式的super()执行(调用Object类的构造方法),并没有什么返回结果,接下来才是在执行HelloA类构造方法的方法体前先执行了HelloA类的构造代码块(I'm A class),再执行HelloA类构造方法的方法体(也就是Hello A),最后又回到HelloB类的构造方法中,这时HelloB类的super()已经执行完了,在执行HelloB类构造方法的方法体前先执行HelloB类的构造代码块(I'm B class),再执行子类构造方法的方法体(HellB)。

无继承初始化顺序:

Java中代码块与代码加载顺序原理的示例分析

有继承初始化顺序:

Java中代码块与代码加载顺序原理的示例分析

接下来看一道阿里笔试题:

public class B{
  public static B t1 = new B();
  public static B t2 = new B();
  {
    System.out.println("构造块");
  }
  static {
    System.out.println("静态块");
  }
  public static void main(String[] args) {
    B t =new B();
  }
}

执行结果:

Java中代码块与代码加载顺序原理的示例分析

总结

Java代码初始化顺序

由 static 关键字修饰的,如类变量和静态代码块,将在类创建实例之前被初始化,而且是按顺序从上到下依次被执行。(类变量、静态代码块)属于类本身,不依赖于类的实例。

没有 static 关键字修饰的(如:实例变量(非静态变量)、非静态代码块)初始化实际上是会被提取到类的构造器中被执行的,但是会比类构造器中的代码块优先执行。实例变量、非静态代码块的地位是相等的,它们将按顺序被执行。
容易混淆的一个知识点

静态方法只允许直接访问静态成员,而实例方法中可以访问静态成员和实例成员,原因是类还没有实例化,所以实例成员也没有被创建,静态方法中因此也不能用this。

关于“Java中代码块与代码加载顺序原理的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

另外有需要云服务器可以了解下创新互联建站www.cdcxhl.com,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。

当前题目:Java中代码块与代码加载顺序原理的示例分析-创新互联
链接地址:https://www.cdcxhl.com/article26/dhcscg.html

成都网站建设公司_创新互联,为您提供网站制作服务器托管软件开发云服务器面包屑导航网站建设

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

商城网站建设