`
Dustin
  • 浏览: 310407 次
  • 性别: Icon_minigender_1
  • 来自: 广州/成都
社区版块
存档分类
最新评论

访问对象的private 方法

阅读更多
 这个问题是跟同学讨论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超时吧,后退找不回来了,只好重敲了一遍,痛:(
分享到:
评论
5 楼 SunMicro 2007-03-29  
Dustin 写道
目送完可否解析一下为什么Java在处理序列化这个问题上要采用添加private方法这种方式呢?

因为这两个方法是由ObjectOutputStream
的writeObject方法和ObjectInputStream
的readObject来调用的,而不是让所有人都可以想当然的调用,从而给编程人员带来误导。就好比将一个key的具体类型告诉给编程人员,这会让程序员以为特定于类型的操作是被鼓励的,但遗憾的是很多情况下并不是这样!
4 楼 FrankTaylor 2007-03-29  
<br/>
<strong>Dustin 写道:</strong><br/>
<div class='quote_div'> 这个问题是跟同学讨论interface Serializable的用法是注意到的。JDK文档中说Serializable 为标记接口(tag interface),实现该接口的类不需要实现任何指定的方法。但是,如果当我们需要自定义序列化过程时,就需要在类中添加两个指定的方法:<br/>
<div class='code_title'>java 代码</div>
<div class='dp-highlighter'>
<div class='bar'/>
<ol class='dp-j'>
    <li class='alt'><span><span class='keyword'>private</span><span> </span><span class='keyword'>void</span><span> writeObject(java.io.ObjectOutputStream out)   </span></span> </li>
    <li class=''><span>     </span><span class='keyword'>throws</span><span> IOException   </span> </li>
    <li class='alt'><span/><span class='keyword'>private</span><span> </span><span class='keyword'>void</span><span> readObject(java.io.ObjectInputStream in)   </span> </li>
    <li class=''><span>     </span><span class='keyword'>throws</span><span> IOException, ClassNotFoundException;   </span> </li>
</ol>
</div>
  嗯,private?确实这样。按常理说,这两个方法应该是被ObjectOutputStream和ObjectInputStream对象的writeObject和readObject方法调用的,这符合面向对象的封装规则:序列化就应该是对象自身的责任。但是,这两个方法设定为private,那么其他对象如何访问呢?当然,因为Serializable对象的序列化工作由jvm内置支持的,因此方法存取权限当然不是问题,但是Java将其设定为private有什么好处呢?<br/>
   其实,我们也可以访问对象的私有方法的,使用反射机制便可:<br/>
<div class='code_title'>java 代码</div>
<div class='dp-highlighter'>
<div class='bar'/>
<ol class='dp-j'>
    <li class='alt'><span><span class='keyword'>import</span><span> java.lang.reflect.Method;   </span></span> </li>
    <li class=''><span>  </span> </li>
    <li class='alt'><span/><span class='keyword'>public</span><span> </span><span class='keyword'>class</span><span> EatApple {   </span> </li>
    <li class=''><span>  </span> </li>
    <li class='alt'><span>    </span><span class='comment'>/** </span>  </li>
    <li class=''><span><span class='comment'>     * @param args </span> </span> </li>
    <li class='alt'><span><span class='comment'>     */</span><span>  </span></span> </li>
    <li class=''><span>    </span><span class='keyword'>public</span><span> </span><span class='keyword'>static</span><span> </span><span class='keyword'>void</span><span> main(String[] args) </span><span class='keyword'>throws</span><span> Exception{   </span> </li>
    <li class='alt'><span>        </span><span class='keyword'>new</span><span> EatApple().eat();   </span> </li>
    <li class=''><span>  </span> </li>
    <li class='alt'><span>    }   </span> </li>
    <li class=''><span>       </span> </li>
    <li class='alt'><span>    </span><span class='keyword'>public</span><span> </span><span class='keyword'>void</span><span> eat() </span><span class='keyword'>throws</span><span> Exception{   </span> </li>
    <li class=''><span>        Apple apple = </span><span class='keyword'>new</span><span> Apple();   </span> </li>
    <li class='alt'><span>        Method m = apple.getClass().getDeclaredMethod(</span><span class='string'>"taste"</span><span>,</span><span class='keyword'>new</span><span> Class[] {});   </span> </li>
    <li class=''><span>        m.setAccessible(</span><span class='keyword'>true</span><span>);   </span> </li>
    <li class='alt'><span>        Object result = m.invoke(apple, </span><span class='keyword'>new</span><span> Object[] {});   </span> </li>
    <li class=''><span>             </span> </li>
    <li class='alt'><span>    }   </span> </li>
    <li class=''><span>}   </span> </li>
    <li class='alt'><span>  </span> </li>
    <li class=''><span/><span class='keyword'>class</span><span> Apple{   </span> </li>
    <li class='alt'><span>       </span><span class='keyword'>private</span><span> </span><span class='keyword'>void</span><span> taste(){   </span> </li>
    <li class=''><span>         System.out.println(</span><span class='string'>"Delicious!"</span><span>);   </span> </li>
    <li class='alt'><span>       }   </span> </li>
    <li class=''><span>    }  </span> </li>
</ol>
</div>
  这个又有什么用处呢?嗯,使用Junit测试私有方法的时候就可以派上用场了,可以看看Bill Venners的叙述:<a href='http://www.artima.com/suiterunner/private.html'><span class='ts'>Testing Private Methods with JUnit and SuiteRunner</span><br/>
</a>  。。敲完以后提示我权限不够,session超时吧,后退找不回来了,只好重敲了一遍,痛:(</div>
<br/>
<br/>
<br/>
312312132<br/>
3 楼 歆渊 2007-03-29  
推荐试试用Opera 上 JavaEye, 可以一直无损失后退.

顺便鄙视一下 IE 和 FireFox.
2 楼 Dustin 2007-03-29  
目送完可否解析一下为什么Java在处理序列化这个问题上要采用添加private方法这种方式呢?
1 楼 shaucle 2007-03-29  
要目送楼主了...

相关推荐

Global site tag (gtag.js) - Google Analytics