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. spring boot踩坑记

    Resolved exception caused by handler execution: org.springframework.http.converter.HttpMessageNotWri ...

  2. golang获取调用者的方法名及所在源码行数

    package main import "runtime" import "log" func main() { test() } func test() { ...

  3. TFTP & commons-net-3.3.jar

    项目需求:上传文件到服务器,TFTP 了解TFTP http://wenku.baidu.com/link?url=MhRVgIySotFMkm5ar6B71zROPMoqC7cd5cSbKJo2kx ...

  4. Qt 在Label上面绘制罗盘

    自己写的一个小小的电子罗盘的一个小程序,不过是项目的一部分,只可以贴绘制部分代码 效果如下图 首先开始自己写的时候,虽然知道Qt 的坐标系是从左上角开始的,所以,使用了算法,在绘制后,在移动回来,但是 ...

  5. CCF-NOIP-2018 提高组(复赛) 模拟试题(四)

    T1 贪吃蛇 [问题描述] 贪吃蛇是一个好玩的游戏.在本题中,你需要对这个游戏进行模拟. 这个游戏在一个 \(n\) 行 \(m\) 列的二维棋盘上进行. 我们用 \((x, y)\) 来表示第 \( ...

  6. result returns more than one elements此种错误,解决

    场景:公司产品开发完成后,接入第三方厂商,在进行接口联调的时候出现此问题.此接口报文中的每一个数据都要进行校验,有些是与已经存入产品数据库中的数据进行对比,看是否存在. 问题:在测试中,有些测试没有问 ...

  7. ADVICE FOR SHORT-TERM MACHINE LEARNING RESEARCH PROJECTS(短期机器学习研究的建议)

    – Tim Rocktäschel, Jakob Foerster and Greg Farquhar, 29/08/2018 Every year we get contacted by stude ...

  8. LeetCode 23 ——合并 K 个排序链表

    1. 题目 2. 解答 2.1. 方法一 在 合并两个有序链表 的基础上,我们很容易想到第一种解法,首先我们将第一个链表和第二个链表合并成一个新的链表,然后再往后依次合并接下来的每个链表即可. 假设每 ...

  9. 可以随着SeekBar滑块滑动显示的Demo

    //关于Seek的自定义样式,之前也有总结过,但是,一直做不出随着滑块移动的效果,查询了很多资料终于解决了这个问题,现在把代码写出来有bug的地方 希望大家批评指正. Step 1 :自定义一个Vie ...

  10. 【SSH】——两种添加jar包方式的比较

    [前言] 在开发过程中,我们对Eclipse或MyEclipse等IDE越来越熟悉了.在使用的过程中,小编了解到两种添加jar包的方式,今天给大家说下这两种方式的差别. 方法一: 将所需要的jar包拷 ...