- Dustin
- 等级:
- 性别:
- 文章: 25
- 积分: 148
- 来自: 广州/成都
|
这个问题是跟同学讨论interface Serializable的用法是注意到的。JDK文档中说Serializable 为标记接口(tag interface),实现该接口的类不需要实现任何指定的方法。但是,如果当我们需要自定义序列化过程时,就需要在类中添加两个指定的方法:
java 代码
- private void writeObject(java.io.ObjectOutputStream out)
- throws IOException
- private void readObject(java.io.ObjectInputStream in)
- throws IOException, ClassNotFoundException;
嗯,private?确实这样。按常理说,这两个方法应该是被ObjectOutputStream和ObjectInputStream对象的writeObject和readObject方法调用的,这符合面向对象的封装规则:序列化就应该是对象自身的责任。但是,这两个方法设定为private,那么其他对象如何访问呢?当然,因为Serializable对象的序列化工作由jvm内置支持的,因此方法存取权限当然不是问题,但是Java将其设定为private有什么好处呢?
其实,我们也可以访问对象的私有方法的,使用反射机制便可:
java 代码
- import java.lang.reflect.Method;
-
- public class EatApple {
-
-
-
-
- public static void main(String[] args) throws Exception{
- new EatApple().eat();
-
- }
-
- public void eat() throws Exception{
- Apple apple = new Apple();
- Method m = apple.getClass().getDeclaredMethod("taste",new Class[] {});
- m.setAccessible(true);
- Object result = m.invoke(apple, new Object[] {});
-
- }
- }
-
- class Apple{
- private void taste(){
- System.out.println("Delicious!");
- }
- }
这个又有什么用处呢?嗯,使用Junit测试私有方法的时候就可以派上用场了,可以看看Bill Venners的叙述: Testing Private Methods with JUnit and SuiteRunner
。。敲完以后提示我权限不够,session超时吧,后退找不回来了,只好重敲了一遍,痛:(
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
返回顶楼 |
|
|
- shaucle
- 等级:
- 性别:
- 文章: 435
- 积分: 443
- 来自: 上海
|
要目送楼主了...
|
返回顶楼 |
|
|
- Dustin
- 等级:
- 性别:
- 文章: 25
- 积分: 148
- 来自: 广州/成都
|
目送完可否解析一下为什么Java在处理序列化这个问题上要采用添加private方法这种方式呢?
|
返回顶楼 |
|
|
- 歆渊
- 等级:
- 性别:
- 文章: 424
- 积分: 1219
|
推荐试试用Opera 上 JavaEye, 可以一直无损失后退.
顺便鄙视一下 IE 和 FireFox.
|
返回顶楼 |
|
|
- FrankTaylor
- 等级: 初级会员
- 文章: 7
- 积分: 30
|
Dustin 写道:
这个问题是跟同学讨论interface Serializable的用法是注意到的。JDK文档中说Serializable 为标记接口(tag interface),实现该接口的类不需要实现任何指定的方法。但是,如果当我们需要自定义序列化过程时,就需要在类中添加两个指定的方法:
java 代码
- private void writeObject(java.io.ObjectOutputStream out)
- throws IOException
- private void readObject(java.io.ObjectInputStream in)
- throws IOException, ClassNotFoundException;
嗯,private?确实这样。按常理说,这两个方法应该是被ObjectOutputStream和ObjectInputStream对象的writeObject和readObject方法调用的,这符合面向对象的封装规则:序列化就应该是对象自身的责任。但是,这两个方法设定为private,那么其他对象如何访问呢?当然,因为Serializable对象的序列化工作由jvm内置支持的,因此方法存取权限当然不是问题,但是Java将其设定为private有什么好处呢?
其实,我们也可以访问对象的私有方法的,使用反射机制便可:
java 代码
- import java.lang.reflect.Method;
-
- public class EatApple {
-
-
-
-
- public static void main(String[] args) throws Exception{
- new EatApple().eat();
-
- }
-
- public void eat() throws Exception{
- Apple apple = new Apple();
- Method m = apple.getClass().getDeclaredMethod("taste",new Class[] {});
- m.setAccessible(true);
- Object result = m.invoke(apple, new Object[] {});
-
- }
- }
-
- class Apple{
- private void taste(){
- System.out.println("Delicious!");
- }
- }
这个又有什么用处呢?嗯,使用Junit测试私有方法的时候就可以派上用场了,可以看看Bill Venners的叙述: Testing Private Methods with JUnit and SuiteRunner
。。敲完以后提示我权限不够,session超时吧,后退找不回来了,只好重敲了一遍,痛:(
312312132
|
返回顶楼 |
|
|
- SunMicro
- 等级:
- 文章: 197
- 积分: 399
|
Dustin 写道 目送完可否解析一下为什么Java在处理序列化这个问题上要采用添加private方法这种方式呢?
因为这两个方法是由ObjectOutputStream
的writeObject方法和ObjectInputStream
的readObject来调用的,而不是让所有人都可以想当然的调用,从而给编程人员带来误导。就好比将一个key的具体类型告诉给编程人员,这会让程序员以为特定于类型的操作是被鼓励的,但遗憾的是很多情况下并不是这样!
|
返回顶楼 |
|
|