import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class TestClass implements Serializable{
private static final long serialVersionUID = 0L;
public TestClass() throws Exception {
throw new Exception("哎呀妈呀,异常啦!!!!");
}
public static void main(String[] args) throws Exception {
byte[] head = { -84, -19, 0, 5, 115, 114, 0 };
byte[] ass = { 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 120, 112 };
String name = TestClass.class.getName();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(head);
baos.write(name.length());
baos.write(name.getBytes());
baos.write(ass);
baos.flush();
baos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
TestClass o = (TestClass) ois.readObject();
ois.close();
System.out.println("创建对象: " + o);
}
}
看到这里先别着急执行,先看看.你觉得能够正常运行吗? 结果是什么?
-----------------------------------------------------------------------------------
运行结果: 创建对象: TestClass@743399
CSDN某帖子 写道
对象创建的几种方法:
1.使用new关键字 2.使用clone方法 3.反射机制 4.反序列化
其中1,3都会明确的显式的调用构造函数
2是在内存上对已有对象的影印 所以不会调用构造函数
4是从文件中还原类的对象 也不会调用构造函数
上述代码就是反序列化的结果
RednaxelaFX 写道
嗯顺带推荐Effective Java, Second Edition的第74条
引用
Normally, objects are created using constructors;
serialization is an extralinguistic mechanism for creating objects. Whether
you accept the default behavior or override it, deserialization is a “hidden constructor”
with all of the same issues as other constructors.
大体的意思是反序列化有一定的风险.破坏了封装.相当于一个隐藏的构造器.
RednaxelaFX 写道
1、Java的实例构造器只负责初始化,不负责创建对象;Java虚拟机的字节码指令的设计也反映了这一点,有一个new指令专门用于创建对象实例,而调用实例构造器则使用invokespecial指令。
2、“this”是作为实例构造器的第一个实际参数传入的。
Java反序列化实际上是调用了基类的构造方法.
ObjectStreamClass中调用ReflectionFactory.newConstructorForSerialization(cl, cons);
- cons = reflFactory.newConstructorForSerialization(cl, cons);
cons = reflFactory.newConstructorForSerialization(cl, cons);
根据cl参数(TestClass类的Class对象)和cons参数(基类Object的构造器)创建了一个新的构造器
打印生成的构造器对象,输出信息为public java.lang.Object(),表面生成的构造器是TestClass父类Object的无参构造器.
但是调用newInstance()的结果却产生了TestClass类的对象.(おかしい......)
ReflectionFactory.newConstructorForSerialization()例子
- Constructor superCons = TestClass.class.getSuperclass().getConstructor();
- System.out.println(superCons);
- ReflectionFactory reflFactory = ReflectionFactory.getReflectionFactory();
- Constructor c = reflFactory.newConstructorForSerialization(TestClass.class,superCons);
- System.out.println(c.newInstance());
Constructor superCons = TestClass.class.getSuperclass().getConstructor();
System.out.println(superCons);
ReflectionFactory reflFactory = ReflectionFactory.getReflectionFactory();
Constructor c = reflFactory.newConstructorForSerialization(TestClass.class,superCons);
System.out.println(c.newInstance());
- public java.lang.Object()
- TestClass@fd13b5
public java.lang.Object()
TestClass@fd13b5
通过基类的方法调用生成了子类.绕开了TestClass类的构造方法.生成了看似不可能存在的TestClass对象
-----------------------------------------------------------------------------------
感谢FX,之前一篇关于构造器的详细论述.传送门http://rednaxelafx.iteye.com/blog/652719
FX写的关于本篇的更详细讲解在这里,传送门http://rednaxelafx.iteye.com/blog/850082
不用构造器也能创建对象
原文:http://blog.csdn.net/zhangming1013/article/details/44618587