是构造方法创建的对象吗

package com.java.essence_36;

import java.util.ArrayList;
import java.util.List; /**
* Created by lw on 14-5-23.
* <p/>
* 构造器做了什么?
* 对象是谁创建的?构造器?
* this究竟是什么?
*/ class SupperConstructorInvocation { SupperConstructorInvocation() {
this(1);//仅仅能是第一句调用其它构造器。默认super();最后递归到Object
//this(1,2); //error
//super(); //error
} SupperConstructorInvocation(double d) {
//this();
System.out.println(d);
} SupperConstructorInvocation(int i, int y) {
//this();
}
} public class ConstructorInvocation extends SupperConstructorInvocation { public void demo() {
//this(); //error ,仅仅能在构造器中调用构造器
} public static void main(String[] args) {
/*ConstructorInvocation constructorInvocation
=new ConstructorInvocation(1);*/
//构造器不能继承 //測试。new对象时候构造器的參数列表运行了吗?
new SupperConstructorInvocation(100 / Math.PI);
//输出31.830988618379067,说明100 / Math.PI运行了才运行构造函数里的内容 /**
* 运行内存
* -Xms1m -Xmx1m
* 运行结果如图1,说明对象创建成功后才去运行构造方法
* 不是构造方法创建的对象
*/
CreateObject.getMaxObjects(); }
} class CreateObject { CreateObject() {
CreateObject object = new CreateObject();
} CreateObject(int temp) {
System.out.println("CreateObject(int temp)->run...");
} private static final List<CreateObject> CREATE_OBJECT_LIST = new ArrayList<>(); public static void getMaxObjects() {
int temp = 0;
while (true) {
try {
CREATE_OBJECT_LIST.add(new CreateObject(temp = 1));
temp = 0;
} catch (Exception e) { } finally {
System.out.println("对象创建时成功时候:构造方法运行了吗?" + (temp == 0));
}
}
}
}

(图1)

CreateObject.getMaxObjects();执行结果



谁创建了对象

运行
javac -p CreateObject.class

反编译查看

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2h1bHVuYg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">


红色部分即为
CreateObject() {
CreateObject object = new CreateObject();
}

反编译内容


指令1 运行父类Object的构造初始化
指令4 运行new 创建对象指令。

依据#2所指向的常量池地址创建一个新对象。

          假设创建成功则将新对象的引用压入栈。
指令8 调用自己的实例方法或者初始化方法。


由此可见:对象是先创建,然后才调用构造方法进行初始化,构造器仅仅是实例化成员。


<init>方法是什么?见:深入讨论类的初始化

this是哪儿来的

实际上是在构造器或者实例方法中都隐式的含有一个參数,这个參数就是类的对象。

class This {

    This() {

    }

    This(int i) {

    }

    /**
* 相当于 This(This this){
} This(This this,int i){
} */ }

对于例如以下代码

This t = new This();

相当于传入一个 new 指令运行后创建对象的引用 r

This t = new This(r);

而不是 t ,由于此时对象还没有初始化,仅仅有对象全然创建后。才会将引用返回并赋值给 t



对于静态方法。当然没有this,由于静态对象和实例无关。而是与类关联。



透析Java本质-谁创建了对象,this是什么的更多相关文章

  1. Java反射机制(创建Class对象的三种方式)

    1:SUN提供的反射机制的类: java.lang.Class<T> java.lang.reflect.Constructor<T> java.lang.reflect.Fi ...

  2. Java基础之创建实例化对象的方式

    Java中创建(实例化)对象的五种方式  1.用new语句直接创建对象,这是最常见的创建对象的方法. 2.通过工厂方法返回对象,如:String str = String.valueOf(23); 3 ...

  3. java通过代理创建Conncection对象与自定义JDBC连接池

    最近学习了一下代理发现,代理其实一个蛮有用的,主要是用在动态的实现接口中的某一个方法而不去继承这个接口所用的一种技巧,首先是自定义的一个连接池 代码如下 import java.lang.reflec ...

  4. java笔试中创建String对象的思考

    题目是这样的下面那些生成新的String对象() A . String  s = new String(); B . String  s = new String("A"); C. ...

  5. java链式创建json对象

    我们主要介绍一下:java中如何通过最简单的方式实现链式创建json对象,解决创建json代码臃肿的问题. 1.假设我们要创建一个json对象格式如下: { "code": 0, ...

  6. Effective Java笔记一 创建和销毁对象

    Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...

  7. Java中new一个子类对象的同时并不会自动创建一个父类对象

    首先重申一个概念:子类会继承父类所有非私有成员变量和方法,包括父类的构造方法 当创建一个子类对象时,首先开辟内存,然后调用类的构造函数,这里的构造函数由两部分组成,一部分是从父类继承而来的父类的构造方 ...

  8. java 创建string对象机制 字符串缓冲池 字符串拼接机制

    对于创建String对象的机制,在这一过程中涉及的东西还是值得探究一番的. 首先看通过new String对象和直接赋值的方式有什么区别,看如下代码: public static void main( ...

  9. Java中的static关键字解析(转自海子)__为什么main方法必须是static的,因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。

    Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...

随机推荐

  1. 关于ListView中getView被重复调用的问题

    我用ListView显示数据时,自定义了一个适配器(extends ArrayAdapter),然后重写了getView方法,现在出现一个问题,就是这个getView()方法被重复调用了,比如我的_d ...

  2. linux CentOS7 安装scala

    1.打开terminal ,进入当前用户路径: cd /home/sks 2.下载Scala2.11 wget https://downloads.lightbend.com/scala/2.11.8 ...

  3. ZH奶酪:PHP上传图片三个步骤

    1. 上传图片三步骤 第一步:首先判断文件类型是否为图片格式,若是则上传文件; 第二步:然后重命名文件(一般都是避免上传文件重名,现在基本上都是以为时间来命名); 第三步:最后把文件上传到指定目录,成 ...

  4. Asp.Net 之 前台绑定常用总结

    1.<%= 变量名 %> 里面放的是后台定义的变量名,如: <div> <p> <%= DateTime.Now.ToString() %></p ...

  5. C# 64位系统调用32位DLL异常解决办法(异常来自HRESULT :0x8007007E)

    解决办法如下 1.在IDE中将目标平台设置成x86(VS是在项目的属性->生成->目标平台) 2.如果DLL中调用了其他的DLL,需要将其他的DLL一同编译 3.有时DLL生成时会依赖于I ...

  6. MySQL 读写分离 使用驱动com.mysql.jdbc.ReplicationDriver

    说明文档:http://dev.mysql.com/doc/refman/5.1/en/connector-j-reference-replication-connection.html 代码例子: ...

  7. Linux学习笔记——Ubuntu更新软件源

    0.前言     通过改动ubuntu软件源可提高apt命令下载安装软件的速度.     參考资料     [官方资料]--配置文件改动方法     [Ubuntu如何改动软件源地址]--使用ubun ...

  8. MISRA-C 2012 C90规范和C99规范对比

  9. OpenERP7.0中日期的问题

    在OpenERP7.0中载入中文语言后,输入某些单据,一些细化到时间的字段输入时会报错,说是日期格式不正确. 解决办法是进入[设置]-[翻译]-[语言]菜单,把时间格式中的值 %I:%M:%S %p ...

  10. MySQL事务控制语句(学习笔记)

    MySQL事务控制语句(学习笔记) MySQL事务控制语句         在mysql命令行的默认下,事务都是自动提交的,sql语句提交后马上会执行commit操作.因此开启一个事务必须使用begi ...