论坛首页 入门技术论坛

访问对象的private 方法

浏览 4376 次
该帖已经被评为新手帖
作者 正文
   发表时间:2007-03-28  
 这个问题是跟同学讨论interface Serializable的用法是注意到的。JDK文档中说Serializable 为标记接口(tag interface),实现该接口的类不需要实现任何指定的方法。但是,如果当我们需要自定义序列化过程时,就需要在类中添加两个指定的方法:
java 代码
  1. private void writeObject(java.io.ObjectOutputStream out)   
  2.      throws IOException   
  3. private void readObject(java.io.ObjectInputStream in)   
  4.      throws IOException, ClassNotFoundException;   
  嗯,private?确实这样。按常理说,这两个方法应该是被ObjectOutputStream和ObjectInputStream对象的writeObject和readObject方法调用的,这符合面向对象的封装规则:序列化就应该是对象自身的责任。但是,这两个方法设定为private,那么其他对象如何访问呢?当然,因为Serializable对象的序列化工作由jvm内置支持的,因此方法存取权限当然不是问题,但是Java将其设定为private有什么好处呢?
   其实,我们也可以访问对象的私有方法的,使用反射机制便可:
java 代码
  1. import java.lang.reflect.Method;   
  2.   
  3. public class EatApple {   
  4.   
  5.     /**  
  6.      * @param args  
  7.      */  
  8.     public static void main(String[] args) throws Exception{   
  9.         new EatApple().eat();   
  10.   
  11.     }   
  12.        
  13.     public void eat() throws Exception{   
  14.         Apple apple = new Apple();   
  15.         Method m = apple.getClass().getDeclaredMethod("taste",new Class[] {});   
  16.         m.setAccessible(true);   
  17.         Object result = m.invoke(apple, new Object[] {});   
  18.              
  19.     }   
  20. }   
  21.   
  22. class Apple{   
  23.        private void taste(){   
  24.          System.out.println("Delicious!");   
  25.        }   
  26.     }  
  这个又有什么用处呢?嗯,使用Junit测试私有方法的时候就可以派上用场了,可以看看Bill Venners的叙述:Testing Private Methods with JUnit and SuiteRunner
  。。敲完以后提示我权限不够,session超时吧,后退找不回来了,只好重敲了一遍,痛:(
   发表时间:2007-03-29  
要目送楼主了...
0 请登录后投票
   发表时间:2007-03-29  
目送完可否解析一下为什么Java在处理序列化这个问题上要采用添加private方法这种方式呢?
0 请登录后投票
   发表时间:2007-03-29  
推荐试试用Opera 上 JavaEye, 可以一直无损失后退.

顺便鄙视一下 IE 和 FireFox.
0 请登录后投票
   发表时间:2007-03-29  

Dustin 写道:
 这个问题是跟同学讨论interface Serializable的用法是注意到的。JDK文档中说Serializable 为标记接口(tag interface),实现该接口的类不需要实现任何指定的方法。但是,如果当我们需要自定义序列化过程时,就需要在类中添加两个指定的方法:
java 代码
  1. private void writeObject(java.io.ObjectOutputStream out)   
  2.      throws IOException   
  3. private void readObject(java.io.ObjectInputStream in)   
  4.      throws IOException, ClassNotFoundException;   
  嗯,private?确实这样。按常理说,这两个方法应该是被ObjectOutputStream和ObjectInputStream对象的writeObject和readObject方法调用的,这符合面向对象的封装规则:序列化就应该是对象自身的责任。但是,这两个方法设定为private,那么其他对象如何访问呢?当然,因为Serializable对象的序列化工作由jvm内置支持的,因此方法存取权限当然不是问题,但是Java将其设定为private有什么好处呢?
   其实,我们也可以访问对象的私有方法的,使用反射机制便可:
java 代码
  1. import java.lang.reflect.Method;   
  2.   
  3. public class EatApple {   
  4.   
  5.     /**  
  6.      * @param args  
  7.      */  
  8.     public static void main(String[] args) throws Exception{   
  9.         new EatApple().eat();   
  10.   
  11.     }   
  12.        
  13.     public void eat() throws Exception{   
  14.         Apple apple = new Apple();   
  15.         Method m = apple.getClass().getDeclaredMethod("taste",new Class[] {});   
  16.         m.setAccessible(true);   
  17.         Object result = m.invoke(apple, new Object[] {});   
  18.              
  19.     }   
  20. }   
  21.   
  22. class Apple{   
  23.        private void taste(){   
  24.          System.out.println("Delicious!");   
  25.        }   
  26.     }  
  这个又有什么用处呢?嗯,使用Junit测试私有方法的时候就可以派上用场了,可以看看Bill Venners的叙述:Testing Private Methods with JUnit and SuiteRunner
  。。敲完以后提示我权限不够,session超时吧,后退找不回来了,只好重敲了一遍,痛:(



312312132
0 请登录后投票
   发表时间:2007-03-29  
Dustin 写道
目送完可否解析一下为什么Java在处理序列化这个问题上要采用添加private方法这种方式呢?

因为这两个方法是由ObjectOutputStream
的writeObject方法和ObjectInputStream
的readObject来调用的,而不是让所有人都可以想当然的调用,从而给编程人员带来误导。就好比将一个key的具体类型告诉给编程人员,这会让程序员以为特定于类型的操作是被鼓励的,但遗憾的是很多情况下并不是这样!
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics