- 浏览: 515045 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (114)
- C基础 (1)
- C指针 (0)
- C语言库函数相关 (1)
- Linux (2)
- Linux网络编程 (1)
- PostgreSQL (0)
- Redis (2)
- Java Web (2)
- JAVA基础 (35)
- Ubuntu (8)
- Android (2)
- MySQL (3)
- 日志 (1)
- 书虫 (1)
- 数据结构 (0)
- 算法 (0)
- 开发工具 (1)
- 转载 (13)
- 英语 (18)
- tomcat启动脚本分析 (3)
- Oracle基础 (4)
- tomcat源码分析 (3)
- tomcat (1)
- Java相关 (1)
- Oracle基本原理--Oracle体系结构 (0)
- Oracle基本原理--表 (0)
- Oracle基本原理--索引 (0)
- Oracle基本原理--事务 (0)
- Oracle开发--SQL (1)
- Oracle基本原理--PL/SQL (0)
- Oracle基本原理--常用函数 (0)
- Oralce管理--用户及权限管理 (0)
- Oracle管理--安装调试 (0)
- Oracle管理--备份恢复 (0)
- Oralce管理--数据迁移 (0)
- Oracle管理--闪回 (0)
- Oracle管理--故障处理 (0)
- Oracle优化原理--统计信息 (0)
- Oracle优化原理--执行计划 (0)
- Oracle优化原理--诊断工具 (0)
- Oracle优化原理--深入理解表 (0)
- Oracle优化原理--深入理解索引 (0)
- Oracle优化原理--表连接原理 (0)
- Java--OOP (0)
- Java--异常 (0)
- Java--泛型 (0)
- Java--集合 (0)
- Java--IO (0)
- Java--枚举类型 (0)
- Java--注释 (0)
- Java--多线程 (0)
- Java--XML (0)
- Java--JDBC (3)
- Servlet (0)
- JSP (0)
- JSTL (0)
- 设计模式 (0)
- DAO与MVC (0)
- Javascript (2)
- Ajax (0)
- JQuery (0)
- HTML/CSS (0)
- 前端相关 (1)
- HTTP (0)
- TCP/IP (0)
- GO基础 (0)
最新评论
-
jsonmong:
推荐一个开发平台,采用的是插件化的设计思想,效果很不错的。ht ...
构建Java Web开发环境 -
wxm198427:
首先表示辛苦了!我想问个问题:我的是windows 7 x64 ...
Oracle 11g R2 for Win7旗舰版(64位)的安装步骤 -
握着橄榄枝的人:
我之前按照你的update mysql.user set pa ...
Windows7下MySQL5.5.20免安装版的配置 -
confident_f:
安装了32的客户端后,用plsql导入导出表有问题,生成不了d ...
Oracle 11g R2 for Win7旗舰版(64位)的安装步骤 -
confident_f:
安装数据库的时候第9步卡住了 是怎么回事呢?
Oracle 11g R2 for Win7旗舰版(64位)的安装步骤
可以用构造器来进行初始化。在运行时刻,可以调用方法或执行某些动作来确定初值,这为编程带来了更大的灵活性。但要牢记:无法阻止自动初始化的进行,它将在构造器被调用之前发生。例如下述代码:
那么i首先会被置为0,然后变为7。对于所有基本类型和对象引用,包括在定义时已经指定初值的变量,这种情况都成立;因此,编译器不会强制你一定要在构造方法的某个地方或在使用它们之前对元素进行初始化——因为初始化早已得到了保证。
1、初始化顺序
在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。例如:
程序运行结果如下:
在House类中,故意把几个Window对象的定义散布到各处,以证明它们全都会在调用构造器或其他方法之前得到初始化。此外,w3在构造器内再次被初始化。
由输出可见,w3这个引用会被初始化两次:一次在调用构造器前,一次在调用期间(第一次引用的对象将被丢弃,并作为垃圾回收)。试想,如果定义了一个重载构造器,它没有初始化w3,;同时在w3的定义里也没有指定默认值,那会产生什么后果呢?所以尽管这种方法似乎效率不高,但它的确能使初始化得到保证。
2、静态数据的初始化
无论创建多少个对象,静态数据都只占用一份存储区域。static关键字不能应用于局部变量,因此它只能作用于域。如果一个域是静态的基本类型域,且也没有对它进行初始化,那么它就会获得基本数据类型的标准初值;如果它是一个对象引用,那么它的默认初始化值就是null。
如果想在定义处进行初始化,采取的方法与非静态数据没什么不同。
要想了解静态存储区域是何时进行初始化的,请看下面的例子:
程序运行结果如下:
Bowl类使得看到类的创建,而Table类和Cupboard类在它们的类定义中加入了Bowl类型的静态数据成员。注意,在静态数据成员定义之前,CupBoard类先定义了一个Bowl类型的非静态数据成员bowl3。
由输出可见,静态初始化只有在必要时刻才会进行。如果不创建Table对象,也不引用Table.bowl1或Table.bowl2,那么静态的Bowl bowl1和bowl2永远都不会被创建。只有在第一个Table对象被初创建(或者第一次访问静态数据)的时候,它们才会被初始化。此后,静态对象不会再次被初始化。
初始化的顺序是先静态对象(如果它们尚未因前面的对象创建过程而被初始化),而后是“非静态”对象。从输出结果中可以观察到这一点。要执行main()(静态方法),必须加载StaticInitialization类,然后其静态域table和cupboard被初始化,这将导致它们对应的类也被加载,并且由于它们也都包含静态的Bowl对象,因此Bowl随后也被加载。这样,在这个特殊的程序中的所有类在main()开始之前就都被加载了。实际情况通常并非如此,因为在典型的程序中,不会像在本例中所做的那样,将所有的事物都通过static联系起来。
总结一下对象创建的过程,假设有个名为Dog的类:
(1)即使没有显式地使用static关键字,构造器实际上也是静态方法。因此,当首次创建类型为Dog的对象时(构造器可以看成静态方法),或者Dog类的静态方法/静态域首次被访问时,Java解释器必须查找类的路径,以定位Dog.class文件。
(2)然后载入Dog.class,有关静态初始化的所有动作都会执行。因此,静态初始化只在Class对象首次加载的时候进行一次。
(3)当用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间。
(4)这块存储空间会被清零,这就自动地将Dog对象中的所有基本数据类型数据都设置成了默认值(对数字来说就是0,对于boolean和char也相同),而引用则被设置成了null。
(5)执行所有出现于字段定义处的初始化动作。
(6)执行构造器。
3、显式的静态初始化
Java允许将多个静态初始化动作组织成一个特殊的“静态句子”(有时也叫做“静态块”)。就像下面这样:
尽管上面的代码看起来像一个方法,但实际只是一段跟在static关键字后面的代码。与其他静态初始化动作一样,这段代码仅执行一次:当首次生成这个类的一个对象时,或者首次访问属于那个类的静态数据成员时(即便从未生成过那个类的对象)。例如:
运行结果1(注释掉(2)):
运行结果2(注释掉(1)):
运行结果3(注释掉(1)和(2)):
运行结果4((1)和(2)均不注释掉):
从上述结果可以看出:无论是通过标为(1)的那行代码访问静态的cup1对象,还是把标为(1)的行注释掉,让它去运行标为(2)的那行代码,Cups的静态初始化动作都会得到执行。如果把标为(1)和(2)的行同时注释掉,Cups静态初始化动作就不会进行,就像在输出中看到的那样。此外,激活一行还是两行标为(2)的代码都无关紧要,静态初始化动作只进行一次。
4、非静态实例初始化
Java中也有被称为实例初始化的类似语法,用来初始化每一个对象的非静态变量。例如:
程序运行的结果如下:
你可以看到实例初始化子句:
看起来它与静态初始化子句一模一样,只不过少了static关键字。这种语法对于支持“匿名内部类”的初始化是必须的,但是它也使得你可以保证无论调用了哪个显式构造器,某些操作都会发生。从输出中可以看到实例初始化子句是在两个构造器之前执行的。
public class Counter{ int i; Counter(){ i = 7; } //...... }
那么i首先会被置为0,然后变为7。对于所有基本类型和对象引用,包括在定义时已经指定初值的变量,这种情况都成立;因此,编译器不会强制你一定要在构造方法的某个地方或在使用它们之前对元素进行初始化——因为初始化早已得到了保证。
1、初始化顺序
在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。例如:
class Window{ Window(int marker){System.out.println("Window("+marker+")");} } class House{ Window w1 = new Window(1); House(){ System.out.println("House()"); w3 = new Window(33); } Window w2 = 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(); } }
程序运行结果如下:
在House类中,故意把几个Window对象的定义散布到各处,以证明它们全都会在调用构造器或其他方法之前得到初始化。此外,w3在构造器内再次被初始化。
由输出可见,w3这个引用会被初始化两次:一次在调用构造器前,一次在调用期间(第一次引用的对象将被丢弃,并作为垃圾回收)。试想,如果定义了一个重载构造器,它没有初始化w3,;同时在w3的定义里也没有指定默认值,那会产生什么后果呢?所以尽管这种方法似乎效率不高,但它的确能使初始化得到保证。
2、静态数据的初始化
无论创建多少个对象,静态数据都只占用一份存储区域。static关键字不能应用于局部变量,因此它只能作用于域。如果一个域是静态的基本类型域,且也没有对它进行初始化,那么它就会获得基本数据类型的标准初值;如果它是一个对象引用,那么它的默认初始化值就是null。
如果想在定义处进行初始化,采取的方法与非静态数据没什么不同。
要想了解静态存储区域是何时进行初始化的,请看下面的例子:
class Bowl{ Bowl(int marker){ System.out.println("Bowl("+marker+")"); } void f1(int marker){ System.out.println("f1("+marker+")"); } } class Table{ static Bowl bowl1 = new Bowl(1); Table(){ System.out.println("Table()"); bowl2.f1(1); } void f2(int marker){ System.out.println("f2("+marker+")"); } 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 marker){ System.out.println("f3("+marker+")"); } static Bowl bowl5 = new Bowl(5); } public class StaticInitialization{ public static void main(String args[]){ System.out.println("Creating new Cupboard() in main"); new Cupboard(); System.out.println("Creating new Cupboard() in main"); new Cupboard(); table.f2(1); cupboard.f3(1); } static Table table = new Table(); static Cupboard cupboard = new Cupboard(); }
程序运行结果如下:
Bowl类使得看到类的创建,而Table类和Cupboard类在它们的类定义中加入了Bowl类型的静态数据成员。注意,在静态数据成员定义之前,CupBoard类先定义了一个Bowl类型的非静态数据成员bowl3。
由输出可见,静态初始化只有在必要时刻才会进行。如果不创建Table对象,也不引用Table.bowl1或Table.bowl2,那么静态的Bowl bowl1和bowl2永远都不会被创建。只有在第一个Table对象被初创建(或者第一次访问静态数据)的时候,它们才会被初始化。此后,静态对象不会再次被初始化。
初始化的顺序是先静态对象(如果它们尚未因前面的对象创建过程而被初始化),而后是“非静态”对象。从输出结果中可以观察到这一点。要执行main()(静态方法),必须加载StaticInitialization类,然后其静态域table和cupboard被初始化,这将导致它们对应的类也被加载,并且由于它们也都包含静态的Bowl对象,因此Bowl随后也被加载。这样,在这个特殊的程序中的所有类在main()开始之前就都被加载了。实际情况通常并非如此,因为在典型的程序中,不会像在本例中所做的那样,将所有的事物都通过static联系起来。
总结一下对象创建的过程,假设有个名为Dog的类:
(1)即使没有显式地使用static关键字,构造器实际上也是静态方法。因此,当首次创建类型为Dog的对象时(构造器可以看成静态方法),或者Dog类的静态方法/静态域首次被访问时,Java解释器必须查找类的路径,以定位Dog.class文件。
(2)然后载入Dog.class,有关静态初始化的所有动作都会执行。因此,静态初始化只在Class对象首次加载的时候进行一次。
(3)当用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间。
(4)这块存储空间会被清零,这就自动地将Dog对象中的所有基本数据类型数据都设置成了默认值(对数字来说就是0,对于boolean和char也相同),而引用则被设置成了null。
(5)执行所有出现于字段定义处的初始化动作。
(6)执行构造器。
3、显式的静态初始化
Java允许将多个静态初始化动作组织成一个特殊的“静态句子”(有时也叫做“静态块”)。就像下面这样:
public class Spoon{ static int i; static{ i =7; } }
尽管上面的代码看起来像一个方法,但实际只是一段跟在static关键字后面的代码。与其他静态初始化动作一样,这段代码仅执行一次:当首次生成这个类的一个对象时,或者首次访问属于那个类的静态数据成员时(即便从未生成过那个类的对象)。例如:
class Cup{ Cup(int marker){ System.out.println("Cup("+marker+")"); } void f(int marker){ System.out.println("f("+marker+")"); } } class Cups{ static Cup cup1; static Cup cup2; static{ cup1 = new Cup(1); cup2 = new Cup(2); } Cups(){ System.out.println("Cups()"); } } public class ExplicitStatic{ public static void main(String args[]){ System.out.println("Inside main()"); Cups.cup1.f(99);//(1) } //static Cups cups1 = new Cups();//(2) //static Cups cups2 = new Cups();//(2) }
运行结果1(注释掉(2)):
运行结果2(注释掉(1)):
运行结果3(注释掉(1)和(2)):
运行结果4((1)和(2)均不注释掉):
从上述结果可以看出:无论是通过标为(1)的那行代码访问静态的cup1对象,还是把标为(1)的行注释掉,让它去运行标为(2)的那行代码,Cups的静态初始化动作都会得到执行。如果把标为(1)和(2)的行同时注释掉,Cups静态初始化动作就不会进行,就像在输出中看到的那样。此外,激活一行还是两行标为(2)的代码都无关紧要,静态初始化动作只进行一次。
4、非静态实例初始化
Java中也有被称为实例初始化的类似语法,用来初始化每一个对象的非静态变量。例如:
class Mug{ Mug(int marker){ System.out.println("Mug("+marker+")"); } void f(int marker){ System.out.println("f("+marker+")"); } } public class Mugs{ Mug mug1; Mug mug2; { mug1 = new Mug(1); mug2 = new Mug(2); System.out.println("mug1&mug2 initialized"); } Mugs(){ System.out.println("Mugs()"); } Mugs(int i){ System.out.println("Mugs(int)"); } public static void main(String args[]){ System.out.println("Inside main()"); new Mugs(); System.out.println("new Mugs() completed"); new Mugs(1); System.out.println("new Mugs(1) completed"); } }
程序运行的结果如下:
你可以看到实例初始化子句:
{ mug1 = new Mug(1); mug2 = new Mug(2); System.out.println("mug1&mug2 initialized"); }
看起来它与静态初始化子句一模一样,只不过少了static关键字。这种语法对于支持“匿名内部类”的初始化是必须的,但是它也使得你可以保证无论调用了哪个显式构造器,某些操作都会发生。从输出中可以看到实例初始化子句是在两个构造器之前执行的。
发表评论
-
foreach循环
2013-06-24 16:15 1433从JDK1.5开始,Java提供了一个更简单的循环:forea ... -
可变参数
2013-06-24 15:38 1193从JDK1.5开始,Java允许使用可变参数为方法指定数量不确 ... -
泛型(core java 笔记)
2013-06-18 16:18 20201.为什么引入泛型 package generic; ... -
两个程序的说明
2010-10-19 09:26 11291、程序1的结果是: clas ... -
成员初始化
2010-10-18 07:55 1195Java尽力保证:所有变量在使用前都能得到恰当的初始化。 对 ... -
线程的死锁
2010-10-11 19:21 1462当两个线程相互等待对方释放同步监视器时就会发生死锁,Java虚 ... -
线程的同步
2010-10-11 19:00 1246一个经典的关于线程安全性的问题:银行取钱问题。 银行取钱的基 ... -
java网站收集
2010-10-10 18:13 1225JAVA开发者最常去的25个英文网站:http://www.i ... -
控制线程
2010-10-10 16:06 19861、线程睡眠:sleep 如果我们需要让当前正在执行的线程暂 ... -
线程的状态
2010-09-28 19:00 995线程从创建到执行完毕的整个过程称为线程的生命周期,在整个生命周 ... -
Java中Thread类的start()和run()的区别
2010-09-27 15:33 40771、start()方法来启动线程,真正实现了多线程运行,这时无 ... -
Java中创建线程的两种方法
2010-09-26 10:18 5609在Java中创建线程有两种方法:继承Thread类和实现Run ... -
创建String对象过程的内存分配小结
2010-09-23 20:32 2744常量池(Constant Pool):指的是在编译期被确定,并 ... -
Java堆和栈的区别 经典总结(转载)
2010-09-18 16:48 1239栈与堆都是Java用来在Ram中存放数据的地方。 与C++不 ... -
Java初学者都必须理解的七大问题
2010-09-18 10:36 1097问题一:我声明了什么 ... -
关于计算java程序运行时间(转载)
2010-09-18 09:22 1090//第一种,伪代码 long startTime= ... -
for循环的优化
2010-09-17 20:29 2107在程序中经常用到for循环,当一些算法实时性要求非常高时,对f ... -
详细解析Java中抽象类和接口的区别(转载)
2010-09-17 10:16 1074在Java语言中,abstract class和inter ... -
集合类(四):Map集合
2010-09-16 20:26 21205、Map集合 Map集合为映射类型,映射与集和列表有明显的区 ... -
集合类(三):Set集合
2010-09-16 19:43 28714、Set集合 Set集合为集类型,集是最简单的一种集合,存放 ...
相关推荐
主要通过实例解析Java中的构造器初始化,代码很简单,叙述很明确,需要的朋友可以了解下。
java 构造器初始化成员变量 是否提供默认构造器 继承中构造器的调用
java 静态_非静态 字段_方法_代码块 子类父类构造_初始化顺序! 三个class 让你清清楚楚 第一个class java代码如下: package initialOrder; class Parent { // 静态变量 public static String p_StaticField...
②重载构造器初始化对角线上的点,public Point(double x); ③编写distance()方法,计算当前点到原点的距离:public double distance(); ④重载double distance(Point p)方法,计算当前点到另外一个点p的距离。 ...
静态字段在静态构造器初始化。 字段是与类或类的实例关联的变量。 使用 static 修饰符声明的字段定义了一个静态字段 (static field)。一个静态字段只标识一个存储位置。无论对一个类创建多少个实例,它的静态字段...
5.7 构造器初始化 5.7.1 初始化顺序 5.7.2. 静态数据的初始化 5.7.3. 显式的静态初始化 5.7.4. 非静态实例初始化 5.8 数组初始化 5.8.1 可变参数列表 5.9 枚举类型 5.10 总结 第6章 访问权限控制 第7章 复用类 第8章...
5.6.1 指定初始化 5.7 构造器初始化 5.7.1 初始化顺序 5.7.2. 静态数据的初始化 5.7.3. 显式的静态初始化 5.7.4. 非静态实例初始化 5.8 数组初始化 5.8.1 可变参数列表 5.9 枚举类型 5.10 总结 第6章 访问权限控制 ...
java构造方法是java类中最重要的一个概念,这篇文档涵盖了,java对象初始化过程中构造器调用的顺序,及作用。
构造器初始化 15 初始化顺序 16 this 和 super 16 访问控制权限 16 继承 17 多态 17 代理 17 Static 17 Final 17 接⼝和抽象类 18 接⼝ 18 抽象类 18 异常 18 认识 Exception 18 什么是 Throwable 18 常⻅的 ...
我们大家都知道,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。我们也可以通过下面的测试代码来验证这一点:
类的初始化 成员初始化 构造器初始化初始化顺序 数组初始化 对象的销毁 对象作用域 this 和 super 访问控制权限继承 多态组合代理 向上转型static final 接口和抽象类接口 抽象类异常 认 识 Exception 什么是 ...
有时,在一个类中有几个构造函数,以容纳某些可选参数,这些构造函数都包含一些共同的代码。 例如,下面的情况: class Car { private string description; private uint nWheels; public Car(string model,...
using System; #region /* /// /// 类定义 /// class Person { //成员变量 int name; int height; //成员方法 void eat() { } } class Test { static void Main() { ... class
构造器概述 Python中的构造器是一种特殊类型的方法,它被用于创建和初始化对象。构造器是在对象被创建之前自动调用的方法,它可以接受参数、返回值和执行任意代码。Python中的构造器由特殊方法`__init__`定义,它...
initializer10-5初始化只读数据10-6在构造器中使用out与ref10-7struct构造器10-7-1struct构造器的限制10-8static构造器10-8-1使用static构造器初始化静态成员10-8-2static构造器的限制10-9对象与内存10-9-l对象的...
initializer10-5初始化只读数据10-6在构造器中使用out与ref10-7struct构造器10-7-1struct构造器的限制10-8static构造器10-8-1使用static构造器初始化静态成员10-8-2static构造器的限制10-9对象与内存10-9-l对象的...
•在java类里只能包含Field,方法,构造器,初始化块,内部类(接口、枚举)等5种成员。 用static修饰的类成员属 于类成员,类Field既可通过类来访问,也可以通过类的对象来访问。当通过对象来访问类属性时,系统会在底...
实例初始化过程:实例初始化就是执行()方法:()方法可能重载有多个,有几个构造器就有几个方法()方法由非静态实例
类的构造器 当创建类对象的时候,会自动调用类的构造器。之前使用的都是默认构造器,我们接下来要学习如何自定义构造器。 主构造器 我们学习过,Java的构造... // 初始化成员变量 this.name = name; this.age = age;
创建一个引用类型的实例时, 首先为实例的数据字段分配内存, 然后初始化对象的附加字段(对象指针、同步块索引), 最后调用类型中定义的实例构造器来设置对象的初始化状态。 构造引用类型的对象时,在调用类型的...