`
Dustin
  • 浏览: 314349 次
  • 性别: 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  
要目送楼主了...

相关推荐

    junit测试private函数

    然而,有时我们可能需要测试私有(private)方法,因为它们可能包含关键逻辑,尽管直接调用它们并不符合面向对象设计的原则。本篇文章将详细介绍如何利用Java的反射机制在JUnit中测试私有函数。 首先,了解Java反射...

    JS中的public和private对象,即static修饰符

    在JavaScript对象字面量中定义的属性和方法默认都是public(公开的),可以在对象外部访问。例如,在Person对象中,_name和_age是public属性,PrintInfo是public方法。通过Person对象,我们可以访问_name属性和调用...

    优化对Private方法进行单元测试Demo

    4. **模拟(Mocking)**:如果private方法依赖于其他服务或对象,可以使用Mockito等库来模拟这些依赖,从而间接测试private方法。但这仍然不是直接测试private方法,而是通过公共接口来验证。 5. **关注SUT(System...

    面向对象修饰符public private protest super final abstract理解

    面向对象编程语言中,诸如Java等,通过不同的访问修饰符来控制类成员(如属性、方法)的可见性和可访问性。这些修饰符包括`public`、`private`、`protected`以及`final`和`abstract`等。下面将详细解释这些关键字的...

    数据访问对象模式

    ### 数据访问对象模式详解 #### 一、概述 在软件开发过程中,特别是在处理与数据库交互的应用程序中,数据访问对象模式(Data Access Object Pattern,简称 DAO 模式)是一种非常实用的设计模式。它旨在将底层的...

    用java代码来解析private、public、default、protected的权限问题

    在Java编程语言中,访问修饰符是控制类成员(如变量、方法和构造器)访问权限的关键要素。本文将深入探讨`private`、`public`、`default`(默认)和`protected`这四种访问权限,并通过代码示例来解析它们在实际编程...

    如何直接访问php实例对象中的private属性详解

    在这个例子中,尽管`$a`是`private`的,但由于两个`A`对象都属于同一类,因此可以互相访问它们的`private`属性。这是因为它们都了解彼此的内部实现细节。 总结来说,直接访问`private`属性通常不是推荐的做法,因为...

    Java反射机制,通过对象访问调用类的私有成员或方法

    要调用私有方法,我们需要使用`Method`类,先获取到该方法的`Method`对象,然后通过`setAccessible(true)`将其访问权限设为可访问,最后通过`invoke()`方法调用: ```java Method privateMethod = personClass....

    Codesys汇川AM600面向对象(动作方法属性).pdf

    在汇川AM600 中,`PRIVATE` 访问修饰符表示方法和属性仅在当前类内部可用,不应被继承;而`PUBLIC` 访问修饰符表示方法和属性在所有地方都可访问,当被继承时,其访问修饰符默认为空,意味着在继承类中同样可访问。 ...

    利用虚函数让private外部访问成为可能!

    虽然这种方法提供了一种绕过私有成员访问限制的方法,但在实际开发中应当谨慎使用。过度依赖这种技术可能会破坏封装原则,导致代码难以维护。此外,还需要注意的是,这种方式只适用于虚函数,对于私有的数据成员仍然...

    Java访问修饰符

    private 方法访问修饰符只能被当前类的方法访问。 缺省(无访问修饰符)方法访问修饰符 缺省方法访问修饰符可以被同一包中的所有类访问。如果子类没有在同一个包中,也不能访问。 static 方法访问修饰符 static ...

    public_protected_private用法详解

    本文将深入探讨Java(以及其他面向对象语言)中的`public`、`protected`和`private`这三个访问修饰符,以及它们在派生类中的应用。 1. **公共访问修饰符(public)** - `public`是最宽松的访问级别,表示任何地方...

    C++ 类访问控制public、private、protected探讨.docx

    C++ 类访问控制是面向对象编程中的核心概念,它涉及到类的数据成员和成员函数的可访问性。在C++中,有三种访问控制修饰符:public、private 和 protected。 1. **Public** 访问控制: 公共成员(public members)...

    举例讲解Python面相对象编程中对象的属性与类的方法

    `self`使得方法能访问对象的属性。 - **对象的方法调用**:例如,`he.fun()`会执行`fun`方法,并可以修改或创建对象的属性。调用`he.var2`或`liu.var2`时,需要确保对象已经执行过相应的初始化方法(如`fun`),...

    实验三:Java类与对象

    访问修饰符(public, private, protected, default)控制类、成员变量和方法的可见性。例如,`Monkey`类中的`name`, `weight`, `age`被声明为私有(`private`),意味着它们只能在类内部访问,而`love`被声明为静态...

    PHP实现在对象之外访问其私有属性private及保护属性protected的方法

    本文实例讲述了PHP实现在对象之外访问其私有属性private及保护属性protected的方法。分享给大家供大家参考,具体如下: public 表示全局的访问权限,类内部外部子类都可以访问; private表示私有的访问权限,只有本...

    Java-面向对象设计-类和对象.docx

    一个类按同种方法产生出来的多个对象,其初始状态都是一样的,但是修改其中一个对象的时候,其他的对象是不会受到影响的。 类的声明和定义在使用类之前,必须先声明它,然后才可以声明变量,并创建对象。类声明的...

    C++ 类访问控制public、private、protected探讨.pdf

    C++ 类访问控制机制是面向对象编程中的核心概念,它主要涉及到`public`、`private`和`protected`这三个访问修饰符。它们的作用是限制类的成员(数据成员和成员函数)在不同作用域内的可访问性,从而实现数据封装和...

Global site tag (gtag.js) - Google Analytics