1、构造函数什么时候被调用,被谁调用?

转摘:http://bbs.csdn.net/topics/350231037

当然,只有在NEW的时候,才会真正的创建这个对象,只有在创建时才会调用该类的构造函数。

如:

Class A{

public A(){

System.out.println("这是A的构造函数");

}

}

Class Test{

public statics void main(String[] args){

A a1;    //--->此时是不会打印出“这是A的构造函数”这段的

a1=new A();    //此时会打印出来

}

}

--------------------

情况当然不限于此了。

毕竟JAVA在创建对象时除了new的方式,还有反射的方式,就是

Class.forName(完整类名)



但反射加载时,只会调用类的无参构造函数。在反射时如果一个类中没有无参构造函数,那是会报实例化异常的。

在同一个类中如果出现构造函数的重载,那也有可能出现其中一个调用另外一个的情况。最显著的情况是因为某些参数采用默认值的方式。



还有创建子类对象时,会自动逐层调用父类的构造函数完成相关的初始化工作。

---------------------

创建该类实例时,会调用类内部构造方法,其实也就是new

上面有说反射的,反射的机制也是调用new关键字构造

不过反射和new在分配上不同 反射是动态的

String str="Me"  是不是分两步的?先是String str=null,然后str=new String("Me")

Class.ForName("").newInstance就可以调用不带参数的构造函数。

事实上例如在这样一个语句:Person ps=new Person();其实实例化了两个对象。Person ps是一个,new Person()是另一个。第一个ps其实就是一个引用其内部存储的是第二个对象的内存地址。所以第二个才是实体对象,所以new时才调用构造方法!!

--------------------

首先你要明白对象创建的几种方法:

1.使用new关键字

2.使用clone方法

3.java的反射机制

4.java的反序列化

以上四种都可以产生java对象

1,3都会明确的显式的调用构造函数

2是在内存上对已有对象的影印 所以不会调用构造函数

4是从文件中还原类的对象 也不会调用构造函数

-------------------

一般情况下,对象可以通过这三种方式创建:

1、构造函数,当然就是NEW的时候调了

2、拷贝构造函数,又有三种情况会调到,作为函数参数,作为返回值,用一个对象去创建另一个对象

当然在JAVA里面Object类都是以引用方式传的,所以在JAVA里面基本上不会在函数调用的时候调用

作为返回值会调用的,clone函数和用一个字符串对象去创建另一个字符串对象就是很好的例子

3、操作符重载

比如像String strHello = "HelloWorld";就是这样的,其实操作符重载也是一个函数



当然,第2和第3太难,JAVA里面都把下层的给屏蔽掉了,但是在下层还是会这样执行的,所以好多人都说C++难就是这些方面

------------------

1 JVM自动创建对象,不需要人为干预.

2 new操作符

3 Class.newInstance(Args)

4 Constructor 对象就是用来创建对象的

java中创建对象要通过new来实现,而构造函数只会在创建对象是才会被调用

只能这么说,万象不离本质,本质上都是通过NEW来创建一个对象,而得到一个对象的方式却可以有多种,并不一定要通过NEW来获得,可以通过设计模式中的单件模式获得一个实例,但内部实现代码无非都是通过NEW来实现的,所以不要给外表骗了,要懂得实质。

最后总结(NEW是本质,其他方式(比如getInstance、反射等)是通过封装后得到的现象)请区分好两者,希望对楼主有帮助。

-------------------

package constructor;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable; public class TestConstructor {
public static void main(String[] args){
System.out.println("========= test new ==========");
Bean b1 = testNew();
b1.setId(1);
b1.setName("b1");
System.out.println(b1);
System.out.println("========= test newInstance ==========");
Bean b2 = testNewInstance();
b2.setId(2);
b2.setName("b2");
System.out.println(b2);
System.out.println("========= test clone ==========");
Bean b3 = testClone(b1);
b3.setName("b3");
System.out.println(b3);
System.out.println("========= test serializeBean&unserializeBean ==========");
serializeBean(b1);
Bean b4 = unserializeBean();
b4.setName("b4");
System.out.println(b4);
} public static Bean testNew(){
Bean b = new Bean();
return b;
}
public static Bean testNewInstance(){
try {
Bean b = Bean.class.newInstance();
return b;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Bean testClone(Bean bean){
try {
Bean b = (Bean)bean.clone();
return b;
} catch (Exception e) {
e.printStackTrace();
}
return null;
} public static void serializeBean(Bean bean){
try {
FileOutputStream fos = new FileOutputStream("bean.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(bean);
oos.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Bean unserializeBean(){
try {
FileInputStream fis = new FileInputStream("bean.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
Bean b = (Bean)ois.readObject();
return b;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
} class Bean implements Cloneable, Serializable{
private static final long serialVersionUID = 8017660448545672348L;
int id;
String name; Bean(){
this(-1, "No Name");
System.out.println("--Bean() called--");
}
public Bean(int id, String name){
this.id = id;
this.name = name;
System.out.println("--Bean(int id, String name) called--");
} public String toString(){
StringBuffer sb = new StringBuffer("Bean@").append(this.hashCode())
.append("[id:").append(id).append("; name:'").append(name).append("']");
return sb.toString();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Bean clone() throws CloneNotSupportedException {
System.out.println("-----clone["+this+"]-----");
return (Bean)super.clone();
}
}

输出:

=========
test new ==========

--Bean(int id, String name) called--

--Bean() called--

Bean@25899876[id:1; name:'b1']

========= test newInstance ==========

--Bean(int id, String name) called--

--Bean() called--

Bean@31131058[id:2; name:'b2']

========= test clone ==========

-----clone[Bean@25899876[id:1; name:'b1']]-----

Bean@5442802[id:1; name:'b3']

========= test serializeBean&unserializeBean ==========

Bean@25699763[id:1; name:'b4']

最初对象的产生,是new或者怎样到内存的,clone和serialized是内存数据的指向或拷贝?最终的本质,都是数据。类似c的malloc,分配一片内存给数据对象。指针或引用,也是占用内存,只是内存的内容是实际对象的地址。

java 构造函数问题的更多相关文章

  1. java构造函数修饰符

    java 构造函数,可以被访问修饰符修饰,而不能被特殊修饰符修饰:(在编译器经过测试) 访问修饰符: public (最常用,其他类的任何位置都可以访问) protected(能够在同一包中被子类访问 ...

  2. JAVA构造函数(方法)

    一.什么是构造函数 java构造函数,也叫构造方法,是java中一种特殊的函数.函数名与相同,无返回值. 作用:一般用来初始化成员属性和成员方法的,即new对象产生后,就调用了对象了属性和方法. 在现 ...

  3. PHP与JAVA构造函数的区别

    早期的PHP是没有面向对象功能的,但是随着PHP发展,从PHP4开始,也加入了面向对象.PHP的面向对象语法是从JAVA演化而来,很多地方类似,但是又发展出自己的特色.以构造函数来说,PHP4中与类同 ...

  4. java构造函数,java的静态块理解

    今天我遇到这样的代码块,理解甚久,现在理解了,举一些例题给你看看 先创建一个One类: package accp.com;/** * 其中一个类 * @author xuxiaohua * */pub ...

  5. java 构造函数内部的多态方法 完全剖析

    我们先来看一个例子,如果你读过<java编程思想>的话 应该会有印象 package com.test.zj; public class PolyConstructors { public ...

  6. java 构造函数

    1.public className(){}. 2.名称与类名相同,无返回值,无返回类型,void也不行.(就是上边的形式,除了可以有参数). 3.有0个或多个参数. 4.每个类都至少有一个const ...

  7. java构造函数使用方法总结

    使用构造器时需要记住: 1.构造器必须与类同名(如果一个源文件中有多个类,那么构造器必须与公共类同名) 2.每个类可以有一个以上的构造器 3.构造器可以有0个.1个或1个以上的参数 4.构造器没有返回 ...

  8. JAVA构造函数简析

    构造函数是java新建对象的一种手段 构造函数可以重载 如果一个类中有多个域,那么就可能需要多个构造函数.这时候,使用重载就可以了 构造函数中this和super的使用 this:(1)this用于本 ...

  9. 关于java构造函数,静态代码块,构造代码块,和普通代码块相关总结(一)

    构造函数.构造代码块和静态代码块容易混淆,它们的执行条件和执行顺序也常常容易犯迷.这里就针对这些问题说一下我个人的一些理解,顺便对这部分内容做个小结. 一.构造函数 格式:类名(参数1,参数2,-){ ...

  10. [ Java学习基础 ] Java构造函数

    构造方法是类中特殊方法,用来初始化类的实例变量,它在创建对象(new运算符)之后自动调用. Java构造方法的特点如下: 构造方法名必须与类名相同. 构造方法没有任何返回值,包括void. 构造方法只 ...

随机推荐

  1. 【Leetcode】605. Can Place Flowers

    Description Suppose you have a long flowerbed in which some of the plots are planted and some are no ...

  2. MVC中输入的保护验证用:HttpServerUtility.HtmlEncode

    安全说明: 上面的代码使用HttpServerUtility.HtmlEncode来保护应用程序的恶意输入 (即 JavaScript).详细信息请参阅如何: 在 Web 应用程序,通过应用 HTML ...

  3. 【Spring实战】----开篇(包含系列目录链接)

    [Spring实战]----开篇(包含系列目录链接) 置顶2016年11月10日 11:12:56 阅读数:3617 终于还是要对Spring进行解剖,接下来Spring实战篇系列会以应用了Sprin ...

  4. 云计算之路-阿里云上:奇怪的CPU 100%问题

    这篇博文记录一下6月1日在阿里云上遇到的奇怪的CPU 100%问题,希望多年以后能真相大白. 那天负载均衡(SLB)中只放了1台云服务器(平时都放2台),由于是节假日,虽然只放了一台,但这台服务器的负 ...

  5. 《数据结构与算法分析:C语言描述》读书笔记

    我们数据结构的课用了这本英文教材,作者是Mark Allen Weiss.总体来说比<算法导论>简单很多,但内容上交集非常大.其实是因为去掉了大多数证明和数学,对于没有耐心看符号和公式的人 ...

  6. 西门子S7-200 SMART在win10环境下,使用虚拟机进行网络通信问题一二

    原来的笔记本光荣退休,新买了小米笔记本17150.有个项目需要使用西门子S7-200 SMART,结果碰到了很多悲催的事情,新系统下的各种问题. 先贴下计算机配置,如下: 阶段一:安装问题 (1)在w ...

  7. storm_jdbc 最完整的版本

    开头:我这里是根据bolt与trident进行分类的,写入和读取的方法可能会在同一个类中,最后会展示一个测试的类来说明怎么用. JdbcSpout:这个类是我写入数据和读取数据的公用spout,细节注 ...

  8. Linux shell 整数运算 let [ ] (( )) expr以及 浮点数 bc用法(转)

    Abstract : 1)  Linux shell 中使用 let , [ ] ,(( )) 三种运算符操作 shell 变量进行简单的基本运算:2)Linux shell 中使用 expr 与 b ...

  9. git - work flow

    git status – Make sure your current area is clean. git pull – Get the latest version from the remote ...

  10. HDU 4588 Count The Carries(数学统计)

    Description One day, Implus gets interested in binary addition and binary carry. He will transfer al ...