Java的对象实例是什么时候被创建
2014-05-30 09:40
288 查看
本文转载2JAVA.NET ,对象实例何时被创建,这个问题也许你用一句话就能回答完了。但是它的潜在陷阱却常常被人忽视,这个问题也许并不像你想的那么简单,不信请你耐心看下去。
我前几天问一个同学,是不是在调用构造函数后,对象才被实例化?他不假思索的回答说是。
请看下面代码:
Java代码
Date date=new Date();
em.out.println(date.getTime());
新手在刚接触构造函数这个概念的时候。他们常常得出这样的结论:对象实例是在调用构造函数后创建的。因为调用构造函数后,调用引用(date)的实例方法便不会报NullPointerException的错误了。
经验者的观点
然而,稍稍有经验的Java程序员便会发现上面的解释并不正确。这点从构造函数中我们可以调用this关键字可以看出。
这段代码中我们在构造函数中已经可以操作对象实例。这也就证明了构造函数其实只是用于初始化,早在进入构造函数之前。对象实例便已经被创建了。
父类构造函数
当创建一个有父类的子类的时候。对象的实例又是何时被创建的呢?我们也许接触过下面经典的代码:
结果是先输出create base,后输出create sub。这个结果看起来和现实世界完全一致,先有老爸,再有儿子。因此我相信有很多程序员跟我一样会认为new SubClass()的过程是:实例化BaseClass->调用BaseClass构造函数初始化->实例化SubClass->调用SubClass构造函数初始化。然而非常不幸的是,这是个错误的观点。
奇怪的代码
以下代码是为了驳斥上面提到的错误观点。但是这种代码其实在工作中甚少出现。
public class BaseClass {
public BaseClass() {
System.out.println("create base");
init();
}
protected void init() {
System.out.println("do init");
}
}
public class SubClass {
public SubClass() {
System.out.println("create sub");
}
@Override
protected void init()
{
assert this != null;
System.out.println("now the working class is:" + this.getClass().getSimpleName());
System.out.println("in SubClass");
}
public static void main(String[] args)
{
new SubClass();
}
}
我前几天问一个同学,是不是在调用构造函数后,对象才被实例化?他不假思索的回答说是。
请看下面代码:
Java代码
Date date=new Date();
em.out.println(date.getTime());
新手在刚接触构造函数这个概念的时候。他们常常得出这样的结论:对象实例是在调用构造函数后创建的。因为调用构造函数后,调用引用(date)的实例方法便不会报NullPointerException的错误了。
经验者的观点
然而,稍稍有经验的Java程序员便会发现上面的解释并不正确。这点从构造函数中我们可以调用this关键字可以看出。
public class Test{ public Test() { this.DoSomething(); } private void DoSomething(){ System.out.println("do init"); } }
这段代码中我们在构造函数中已经可以操作对象实例。这也就证明了构造函数其实只是用于初始化,早在进入构造函数之前。对象实例便已经被创建了。
父类构造函数
当创建一个有父类的子类的时候。对象的实例又是何时被创建的呢?我们也许接触过下面经典的代码:
public class BaseClass { public BaseClass(){ System.out.println("create base"); } } public class SubClass{ public SubClass() { System.out.println("create sub"); } public static void main(String[] args) { new SubClass(); } }
结果是先输出create base,后输出create sub。这个结果看起来和现实世界完全一致,先有老爸,再有儿子。因此我相信有很多程序员跟我一样会认为new SubClass()的过程是:实例化BaseClass->调用BaseClass构造函数初始化->实例化SubClass->调用SubClass构造函数初始化。然而非常不幸的是,这是个错误的观点。
奇怪的代码
以下代码是为了驳斥上面提到的错误观点。但是这种代码其实在工作中甚少出现。
public class BaseClass {
public BaseClass() {
System.out.println("create base");
init();
}
protected void init() {
System.out.println("do init");
}
}
public class SubClass {
public SubClass() {
System.out.println("create sub");
}
@Override
protected void init()
{
assert this != null;
System.out.println("now the working class is:" + this.getClass().getSimpleName());
System.out.println("in SubClass");
}
public static void main(String[] args)
{
new SubClass();
}
}
相关文章推荐
- java通过暴力反射创建不可实例化类的对象实例
- 关于java中创建对象实例
- Java中的static关键字解析(转自海子)__为什么main方法必须是static的,因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。
- Java中的垃圾回收问题以及在创建对象的时候的内存的分析
- 透析Java本质-谁创建了对象,this是什么
- JAVA中创建一个对象有哪几种方法,有什么区别?
- 透析Java本质-谁创建了对象,this是什么
- Java创建对象实例的三种方法
- 今天发现c#中的实例后的对象是不能调用静态方法,以前学Java的时候是可以的.
- java中在创建对象时候的初始化顺序
- Java中如何实现一个类在内存里只能创建一个实例对象
- java 程序加载过程---3--类中申明同时申明类的静态对象 创建类的实例 访问类的静态变量 调用类的静态方法 使用反射方法 初始化类的子类对象 直接使用java.exe 调用某个类
- (JAVA自学笔记)创建一个对象都在内存中做了什么事情
- 对象在创建的时候都发生了什么?
- 第2章 Java编程基础——FAQ2.22 创建String对象时, 使用String s=new String (“abc”)和String s=“abc”语句有什么区别?
- java创建对象实例的三种方法
- 实例变量的初始化,构造器在new - 创建实例对象的时候,才会调用执行
- java 程序加载过程---2-创建类实例对象
- java动态代理对象实例的创建
- Effective Java Item5-在可以重用对象的时候避免创建对象