实例解析Java中的构造器初始化

1.初始化顺序
  当Java创建一个对象时,系统先为该对象的所有实例属性分配内存(前提是该类已经被加载过了),接着程序开始对这些实例属性执行初始化,其初始化顺序是:先执行初始化块或声明属性时制定的初始值,再执行构造器里制定的初始值。 在类的内部,变量定义的先后顺序决定了初始化的顺序,即时变量散布于方法定义之间,它们仍就会在任何方法(包括构造器)被调用之前得到初始化。

class Window {
  Window(int maker) {
    System.out.println("Window(" + maker + ")");
  }
}
class House {
  Window window1 = new Window(1);
  House() {
    System.out.println("House()");
    w3 = new Window(33);
  }
  Window window2 = new Window(2);
  void f() {
    System.out.println("f()");
  }
  Window w3 = new Window(3);
}
public class OrderOfInitialization {
  public static void main(String[] args) {
    House h = new House();
    h.f();
  }
}

运行结果:

Window(1)
Window(2)
Window(3)
House()
Window(33)
f()

由输出可见,w3这个引用会被初始化两次:一次在调用构造器之前,一次在调用期间(第一次引用的对象将被丢弃,并作为垃圾回收)。

2.静态数据的初始化
  无论创建多少个对象,静态数据都只占一份存储区域。static关键字不能应用于局部变量,因此它只能作用于域。

class Bowl {
  Bowl(int maker) {
    System.out.println("Bowl(" + maker + ")");
  }
  void f1(int maker) {
    System.out.println("f1(" + maker + ")");
  }
}
class Table {
  static Bowl bowl1 = new Bowl(1);
  Table() {
    System.out.println("Table()");
    bowl2.f1(1);
  }
  void f2(int maker) {
    System.out.println("f2(" + maker + ")");
  }
  static Bowl bowl2 = new Bowl(2);
}

class Cupboard {
  Bowl bowl3 = new Bowl(3);
  static Bowl bowl4 = new Bowl(4);
  Cupboard() {
    System.out.println("CupBoard()");
    bowl4.f1(2);
  }
  void f3(int maker) {
    System.out.println("f3(" + maker + ")");
  }
  static Bowl bowl5 = new Bowl(5);
}
public class StaticInitialization {
  public static void main(String[] args) {
    System.out.println("created new Cupboard() in main");
    new Cupboard();
    System.out.println("created new Cupboard in main");
    new Cupboard();
    table.f2(1);
    cupboard.f3(1);
  }
  static Table table = new Table();
  static Cupboard cupboard = new Cupboard();
}

运行结果:

Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
CupBoard()
f1(2)
created new Cupboard() in main
Bowl(3)
CupBoard()
f1(2)
created new Cupboard in main
Bowl(3)
CupBoard()
f1(2)
f2(1)
f3(1)

从某种程度上来看,初始化是一段固定执行的代码,它不能接受任何参数。因此初始化块对同一个类所有对象所进行的初始化处理完全相同。基于这个原因,不难发现初始化块的基本用法,如果有一段初始化处理代码对所有对象完全相同,且无须接受任何参数,就可以把这段初始化处理代码提取到初始化块中。

以上就是本文关于实例解析Java中的构造器初始化的全部内容,希望对大家有所帮助。

(0)

相关推荐

  • Java中static静态变量的初始化完全解析

    静态变量初始化顺序 1.简单规则 首先先看一段最普遍的JAVA代码: public class Test { public static Test1 t = new Test1(); public static int a = 0; public static int b; public static void main(String[] arg) { System.out.println(Test.a); System.out.println(Test.b); } } class Test1

  • JavaWeb中web.xml初始化加载顺序详解

    需求说明 做项目时,为了省事,起初把初始化的配置都放在每个类中 static加载,初始化配置一多,就想把它给整理一下,这里使用servlet中的init方法初始化. web.xml说明 首先了解下web.xml中元素的加载顺序: 启动web项目后,web容器首先回去找web.xml文件,读取这个文件 容器会创建一个 ServletContext ( servlet 上下文),整个 web 项目的所有部分都将共享这个上下文 容器将 转换为键值对,并交给 servletContext 容器创建 中的

  • 深入介绍Java对象初始化

    前言 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的. 自动初始化(默认值) 一个类的所有基本数据成员都会得到初始化,运行下面的例子可以查看这些默认值: class Default{ boolean t; char c; byte b; short s; int i; long l; float f; double d; public void show() { System.out.println("基本类型 初始化值\n"+ "bo

  • Java 数组声明、创建、初始化详解

    一维数组的声明方式: type var[]; 或type[] var; 声明数组时不能指定其长度(数组中元素的个数), Java中使用关键字new创建数组对象,格式为: 数组名 = new 数组元素的类型 [数组元素的个数] 实例: TestNew.java: 程序代码: public class TestNew { public static void main(String args[]) { int[] s ; int i ; s = new int[5] ; for(i = 0 ; i

  • Java中对象初始化顺序的详细介绍

    前言 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.最近我发现了一个有趣的问题,这个问题的答案乍一看下骗过了我的眼睛.看一下这三个类: package com.ds.test; public class Upper { String upperString; public Upper() { Initializer.initialize(this); } } package com.ds.test; public class Lower extends

  • Java中初始化块详解及实例代码

    Java中初始化块详解 在Java中,有两种初始化块:静态初始化块和非静态初始化块. 静态初始化块:使用static定义,当类装载到系统时执行一次.若在静态初始化块中想初始化变量,那仅能初始化类变量,即static修饰的数据成员. 非静态初始化块:在每个对象生成时都会被执行一次,可以初始化类的实例变量. 非静态初始化块会在构造函数执行时,且在构造函数主体代码执行之前被运行. 括号里的是初始化块,这里面的代码在创建Java对象时执行,而且在构造器之前执行! 其实初始化块就是构造器的补充,初始化块是

  • 实例解析Java中的构造器初始化

    1.初始化顺序 当Java创建一个对象时,系统先为该对象的所有实例属性分配内存(前提是该类已经被加载过了),接着程序开始对这些实例属性执行初始化,其初始化顺序是:先执行初始化块或声明属性时制定的初始值,再执行构造器里制定的初始值. 在类的内部,变量定义的先后顺序决定了初始化的顺序,即时变量散布于方法定义之间,它们仍就会在任何方法(包括构造器)被调用之前得到初始化. class Window { Window(int maker) { System.out.println("Window(&quo

  • 实例解析JAVA中代码的加载顺序

    Java中代码的加载顺序所能了解的知识点 类的依赖关系 static代码块的加载时间 继承类中构造器的隐式调用 非static的成员变量初始化时间 main方法和static的加载顺序 测试代码如下: public class App { private static App d = new App(); private SubClass t = new SubClass(); static{ System.out.println("App static");//6 } public

  • 实例解析Java中的synchronized关键字与线程安全问题

    首先来回顾一下synchronized的基本使用: synchronized代码块,被修饰的代码成为同步语句块,其作用的范围是调用这个代码块的对象,我们在用synchronized关键字的时候,能缩小代码段的范围就尽量缩小,能在代码段上加同步就不要再整个方法上加同步.这叫减小锁的粒度,使代码更大程度的并发. synchronized方法,被修饰的方法成为同步方法,其作用范围是整个方法,作用对象是调用这个方法的对象. synchronized静态方法,修饰一个static静态方法,其作用范围是整个

  • 解析Java中的static关键字

    一.static关键字使用场景 static关键字主要有以下5个使用场景: 1.1.静态变量 把一个变量声明为静态变量通常基于以下三个目的: 作为共享变量使用 减少对象的创建 保留唯一副本 第一种比较容易理解,由于static变量在内存中只会存在一个副本,所以其可以作为共享变量使用,比如要定义一个全局配置.进行全局计数.如: public class CarConstants { // 全局配置,一般全局配置会和final一起配合使用, 作为共享变量 public static final in

  • 通过实例解析java8中的parallelStream

    这篇文章主要介绍了通过实例解析java8中的parallelStream,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 about Stream 什么是流? Stream是java8中新增加的一个特性,被java猿统称为流. Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator.原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作:高级版本的 Stream

  • 解析java中的condition

    一.condition 介绍及demo Condition是在java 1.5中才出现的,它用来替代传统的Object的wait().notify()实现线程间的协作,相比使用Object的wait().notify(),使用Condition的await().signal()这种方式实现线程间协作更加安全和高效.因此通常来说比较推荐使用Condition,阻塞队列实际上是使用了Condition来模拟线程间协作. Condition是个接口,基本的方法就是await()和signal()方法:

  • 分别在Groovy和Java中创建并初始化映射的不同分析

    目录 安装 Java 和 Groovy Groovy 相关资源 Java 和 Groovy 中的映射map都是非常通用的,它允许关键字key和值value为任意类型,只要继承了 Object 类即可. 我最近在探索 Java 与 Groovy 在 创建并初始化列表List 和 在运行时构建列表List 方面的一些差异.我观察到,就实现这些功能而言,Groovy 的简洁和 Java 的繁复形成了鲜明对比. 在这篇文章中,我将实现在 Java 和 Groovy 中创建并初始化映射Map.映射为开发支

  • 图文详解Java中class的初始化顺序

    class的装载 在讲class的初始化之前,我们来讲解下class的装载顺序. 以下摘自<Thinking in Java 4> 由于Java 中的一切东西都是对象,所以许多活动 变得更加简单,这个问题便是其中的一例.正如下一章会讲到的那样,每个对象的代码都存在于独立的文件中.除非真的需要代码,否则那个文件是不会载入的.通常,我们可认为除非那个类的一个对象构造完毕,否则代码不会真的载入.由于static 方法存在一些细微的歧义,所以也能认为"类代码在首次使用的时候载入".

  • 老生常谈java中的数组初始化

    数组的初始化可以分为两种: 1.静态初始化 2.动态初始化 静态初始化: 例: String[] str = new String[]{"A","B","C"}; String str[] = new String[]{"A","B","C"}; String str = {"A","B","C"}; 动态初始化: 例: Str

  • 实例讲解Java中的synchronized

    一.使用场景 在负责后台开发的时候,很多时候都是提供接口给前端开发人员去调用,会遇到这样的场景: 需要提供一个领奖接口,每个用户名只能领取一次,我们可以将成功领取的用户在数据库用个标记保存起来.如果这个用户再来领取的时候,查询数据库看该用户是否领取过. 但是问题来了,假设用户手速很快,极短时间内点了两次领奖按钮(前端没有进行控制,我们也不能依赖前端去控制).那么可能掉了两次领奖接口,而且有可能第二次调用的时候查询数据库的时候,第一次领奖还没有执行完成更新领奖标记. 这种场景就可以使用到synch

随机推荐