java创建对象方法列表
2015-12-10 15:29
381 查看
引用
不用构造方法也能创建对象前言
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表达式方式
直接调用函数构造器,实际上由以下两个步骤完成创建空对象,(此时类型已经是正确的),字节码为new
调用某个版本的构造器,对应的字节码是
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的反序列化实际上是调用了基类的构造方法,创建对象也是两个步骤:
创建出空对象(此时类型已经是正确的了)
调用用户自定义的反序列化方法(readObject,如果有的话)或者调用默认的反序列化方法。
allocateInstance方式
其实allocateInstance方式也只是反序列化方式中的一种。这里只是简单的介绍一下。相关文章推荐
- ubuntu上 使用eclipse搭建stm32开发环境遇到的问题
- SpringMVC返回json数据的配置方式
- Java中的异常、断言、日志 log4j
- spring含参数 环绕通知demo
- java—连接池 C3p0 DBCP
- 谈论高并发(二十二)解决java.util.concurrent各种组件(四) 深入了解AQS(二)
- JavaEE_Mybatis_SpringMVC_自定义的参数绑定,页面的日期类型传递到数据库中datetime
- Java自动装箱与拆箱问题研究
- java的static块执行时机<转>
- MyBatis与Spring集成
- Java map详解 - 用法、遍历、排序、常用API等
- Android——Eclipse打包apk并用命令行安装
- java环境变量
- Java RMI之HelloWorld篇
- day_36Java对象内存管理
- SpringMVC配置XML
- spring事务回滚
- SpringMVC配置XML
- Eclipse使用基础知识
- java自动装箱和拆箱