引用

  • 不用构造方法也能创建对象

前言

java中对象创建的方法主要包括,1,使用new关键字,2.使用clone方法,3.反射机制,4.反序列化。其中1,3都会明确的显式的调用构造函数。2是在内存上对已有对象的影印,所以不会调用构造函数。4是从文件中还原类的对象,也不会调用构造函数。本文将简要列举这些对象创建的方法,并做一些简单的分析总结。

创建对象的方法

调用构造函数

  • 代码如下所示:
public class ConstructorTest {public ConstructorTest() { System.out.println("run in constructor"); } public static void main(String[] args) throws Exception { //使用new构建对象 ConstructorTest t1 = new ConstructorTest(); System.out.println(t1); //使用反射构建对象 Class<?> clazz = Class.forName("org.editice.study.constructor.ConstructorTest"); Constructor<?> cons[] = clazz.getConstructors(); ConstructorTest t2 = (ConstructorTest) cons[0].newInstance(); System.out.println(t2); } }

new表达式方式

  • 直接调用函数构造器,实际上由以下两个步骤完成
    1. 创建空对象,(此时类型已经是正确的),字节码为new
    1. 调用某个版本的构造器,对应的字节码是invokespecial <init>
  • 字节码如图:

反射方式

  • 反射调用函数构造器,字节码如下图所示

不调用构造函数

  • 代码如下所示:
public class InstanceWithoutConstructorTest {public InstanceWithoutConstructorTest() { System.out.println("run in constructor"); } public static void main(String[] args) throws Exception{ //allocateInstance方式 Field f = Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); Unsafe us = (Unsafe) f.get(null); InstanceWithoutConstructorTest t1 = (InstanceWithoutConstructorTest) us.allocateInstance(InstanceWithoutConstructorTest.class); System.out.println(t1); //java反序列化方式 ReflectionFactory rf = ReflectionFactory.getReflectionFactory(); Constructor constructor = rf.newConstructorForSerialization(InstanceWithoutConstructorTest.class, Object.class.getConstructor()); InstanceWithoutConstructorTest t2 = (InstanceWithoutConstructorTest) constructor.newInstance(); System.out.println(t2); } }
  • 运行结果如下所示:

java反序列化方式

  • 在Sun Jdk的实现里,java层面的反射类库与JVM层面的反射实现相互配合来完成反序列化。java.io.ObjectStreamClass通过跟反射方法/构造器调用类似的机制来获取所谓的“序列化构造器”,在反序列化的时候调用这个版本的构造器。
  • 创建“序列化构造器”时要在继承链里从最具体向最抽象的方向搜索,找到第一个不可序列化的类(没有实现Serializable接口的类),并找出它的无参构造器来调用。也就是说反序列化的时候并不是完全不调用用户代码里面声明的构造器,只是不调用实现了Serializable的类而已。ps:实际上都是调用了object的无参构造器。
  • java的反序列化实际上是调用了基类的构造方法,创建对象也是两个步骤:
    1. 创建出空对象(此时类型已经是正确的了)
    1. 调用用户自定义的反序列化方法(readObject,如果有的话)或者调用默认的反序列化方法。

allocateInstance方式

  • 其实allocateInstance方式也只是反序列化方式中的一种。这里只是简单的介绍一下。

转载于:https://www.cnblogs.com/ieiang/p/6430732.html

java创建对象方法列表(转)相关推荐

  1. 遍历Java中的列表的方法

    本文翻译自:Ways to iterate over a list in Java Being somewhat new to the Java language I'm trying to fami ...

  2. java 可变参数列表_java中可变参数列表的实现方法

    我们在对可变参数有一定的认识后,可以引申一下它的使用范围.在数组中也会需要参数的传入,那么结合参数的数量不固定,我们在参数类型上也得到了增加,这就是本篇所要讲的可变参数列表.下面我们就java可变参数 ...

  3. java创建对象的过程_Java创建对象的过程

    Java创建对象的过程 Java是一门面向对象的编程语言,在Java程序运行过程中每时每刻都有对象被创建出来.在语言层面上,创建对象通常仅仅是一个new关键字而已,而在虚拟机中,对象的创建又是怎样一个 ...

  4. 近5年133个Java面试问题列表

    2019独角兽企业重金招聘Python工程师标准>>> Java 面试随着时间的改变而改变.在过去的日子里,当你知道 String 和 StringBuilder 的区别就能让你直接 ...

  5. 太肝了、最近5年183个Java面试问题列表及回答(值得收藏)

    作者: YHGui https://github.com/YHGui/easy-job/ 精彩推荐 一百期Java面试题汇总 SpringBoot内容聚合 IntelliJ IDEA内容聚合 Myba ...

  6. javaScript中创建对象和Java创建对象的区别

    1. 前言 作为Java 帝国的未来继承人,Java小王子受到了严格的教育, 不但精通Java语言.Java虚拟机.java类库和框架,还对各种官方的Java规范了如指掌. 近日他听说一个叫做Java ...

  7. Java中方法的重写(overriding)和重载(overloading)的区别

    Java中方法的重写(overriding)和重载(overloading) 重写 在子类中可以根据需要对从父类中继承来的方法进行改造,也称为重置.覆盖. 在子类中创建一个和父类中的一个相同名字.相同 ...

  8. Java中方法的学习

    目录 概述 第一章:Java中的方法是什么意思 (1)Java中方法的定义 ①方法的修饰符 ②方法的返回值类型 ③方法名 ④方法的参数列表 ⑤方法体 第二章:方法的重载和重写 (1)方法的重载 (2) ...

  9. Java创建对象的过程

    java创建对象的过程主要分为一下五个步骤: (1)类加载检查 Java虚拟机(jvm)在读取一条new指令时候,首先检查能否在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否被加载. ...

最新文章

  1. 【WebAPI No.5】Core WebAPI中的自定义格式化
  2. ***测试之情报收集
  3. android点击事件的优先级,android中进程的优先级
  4. 【机器学习】机器学习视角下的因果推断
  5. 在Red Hat 4 AS U7上安装oracle10gR2
  6. 一个人幸运的前提,是他有能力改变自己
  7. 微服务间保持事务一致性
  8. python装饰器property_python装饰器: @property
  9. 怎样用python把数据分开_python使用pandas实现数据分割实例代码
  10. Entity Framework 小知识(一)
  11. java输出横纵坐标点_java编程 知道坐标求三角形 做了一部分题目要求写出一个Point(点)类,该类具有x,y(表示点的横、纵坐标)两个属...
  12. 新手干货:Vue - 事件修饰符
  13. 3dmax无法显示缩略图 或者 缩略图显示为黑色 -解决方法
  14. c语言入门教程怎么编程,从零开始的C语言入门教程-编程语言的基础
  15. 20个励志早会小故事
  16. vbox虚拟机系统转移到vmware虚拟机中
  17. DLL文件如何还原打开方式
  18. windows下编译64位x264
  19. 搭建商城的微服务架构-2
  20. VS2022安装EasyX 及 EasyX图形库安装和使用(附C++各图形编程项目示例源码)

热门文章

  1. 找出数组中只出现过一次的数
  2. http发送16进制报文_图解HTTP 第三章HTTP报文内的HTTP信息
  3. python123第四周作业_科学计算和可视化
  4. centos oracle 修改监听服务名_Oracle-Oracle DB、监听和oem开机启动
  5. jqGrid获取数据库数据的方式
  6. PHP中include和require的区别详解
  7. apache 下载安装linux,linux下安装apache详解
  8. php mysql合同跟踪,使用TCP协议进行路由跟踪
  9. MyBatis Plus 导入IdType失败
  10. scala的函数化编程