⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tij0116.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 5 页
字号:
sensitive information that you don’t want to serialize, such as a
password. Even if that information is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">in
the object, once it&#8217;s serialized it&#8217;s possible for someone to
access it by reading a file or intercepting a network transmission.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">One
way to prevent sensitive parts of your object from being serialized is to
implement your class as 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Externalizable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
as shown previously. Then nothing is automatically serialized and you can
explicitly serialize only the necessary parts inside 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>writeExternal(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If
you&#8217;re working with a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Serializable
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">object,
however, all serialization happens automatically. To control this, you can turn
off serialization on a field-by-field basis using the <A NAME="Index1331"></A><A NAME="Index1332"></A><A NAME="Index1333"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>transient</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword, which says &#8220;Don&#8217;t bother saving or restoring this &#8211;
I&#8217;ll take care of it.&#8221;
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">For
example, consider a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Login
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">object
that keeps information about a particular login session. Suppose that, once you
verify the login, you want to store the data, but without the password. The
easiest way to do this is by implementing <A NAME="Index1334"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Serializable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and marking the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>password</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
field as 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>transient</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Here&#8217;s what it looks like:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Logon.java</font>
<font color="#009900">// Demonstrates the "transient" keyword</font>
<font color="#0000ff">import</font> java.io.*;
<font color="#0000ff">import</font> java.util.*;

<font color="#0000ff">class</font> Logon <font color="#0000ff">implements</font> Serializable {
  <font color="#0000ff">private</font> Date date = <font color="#0000ff">new</font> Date();
  <font color="#0000ff">private</font> String username;
  <font color="#0000ff">private</font> <font color="#0000ff">transient</font> String password;
  Logon(String name, String pwd) {
    username = name;
    password = pwd;
  }
  <font color="#0000ff">public</font> String toString() {
    String pwd =
      (password == <font color="#0000ff">null</font>) ? "(n/a)" : password;
    <font color="#0000ff">return</font> "logon info: \n   " +
      "username: " + username +
      "\n   date: " + date.toString() +
      "\n   password: " + pwd;
  }
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    Logon a = <font color="#0000ff">new</font> Logon("Hulk", "myLittlePony");
    System.out.println( "logon a = " + a);
    <font color="#0000ff">try</font> {
      ObjectOutputStream o =
        <font color="#0000ff">new</font> ObjectOutputStream(
          <font color="#0000ff">new</font> FileOutputStream("Logon.out"));
      o.writeObject(a);
      o.close();
      <font color="#009900">// Delay:</font>
      <font color="#0000ff">int</font> seconds = 5;
      <font color="#0000ff">long</font> t = System.currentTimeMillis()
             + seconds * 1000;
      <font color="#0000ff">while</font>(System.currentTimeMillis() &lt; t)
        ;
      <font color="#009900">// Now get them back:</font>
      ObjectInputStream in =
        <font color="#0000ff">new</font> ObjectInputStream(
          <font color="#0000ff">new</font> FileInputStream("Logon.out"));
      System.out.println(
        "Recovering object at " + <font color="#0000ff">new</font> Date());
      a = (Logon)in.readObject();
      System.out.println( "logon a = " + a);
    } <font color="#0000ff">catch</font>(Exception e) {
      e.printStackTrace();
    }
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can see that the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>date</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>username</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
fields are ordinary (not 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>transient</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">),
and thus are automatically serialized. However, the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>password</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>transient</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and so is not stored to disk; also the serialization mechanism makes no attempt
to recover it. The output is:
</FONT><P></DIV>

<font color="#990000"><PRE>logon a = logon info:
   username: Hulk
   date: Sun Mar 23 18:25:53 PST 1997
   password: myLittlePony
Recovering object at Sun Mar 23 18:25:59 PST 1997
logon a = logon info:
   username: Hulk
   date: Sun Mar 23 18:25:53 PST 1997
   password: (n/a) </PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">When
the object is recovered, the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>password</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
field is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>null</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Note that 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>toString(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
must check for a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>null</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
value of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>password
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">because
if you try to assemble a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object using the overloaded &#8216;
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>+</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">&#8217;
operator, and that operator encounters a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>null</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
handle, you&#8217;ll get a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>NullPointerException.</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(Newer versions of Java might contain code to avoid this problem.)
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can also see that the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>date</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
field is stored to and recovered from disk and not generated anew.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Since
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Externalizable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects do not store any of their fields by default, the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>transient</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword is for use with 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Serializable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects only.
</FONT><P></DIV>
<A NAME="Heading347"></A><H4 ALIGN=LEFT>
An
alternative to Externalizable
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If
you&#8217;re not keen on implementing the <A NAME="Index1335"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Externalizable
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">interface,
there&#8217;s another approach. You can implement the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Serializable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
interface and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>add
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">(notice
I say &#8220;add&#8221; and not &#8220;override&#8221; or
&#8220;implement&#8221;) methods called <A NAME="Index1336"></A><A NAME="Index1337"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>writeObject(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and <A NAME="Index1338"></A><A NAME="Index1339"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>readObject(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that will automatically be called when the object is serialized and
deserialized, respectively. That is, if you provide these two methods they will
be used instead of the default serialization.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
methods must have these exact signatures:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#0000ff">private</font> <font color="#0000ff">void</font> 
  writeObject(ObjectOutputStream stream)
    <font color="#0000ff">throws</font> IOException;

<font color="#0000ff">private</font> <font color="#0000ff">void</font> 
  readObject(ObjectInputStream stream)
    <font color="#0000ff">throws</font> IOException, ClassNotFoundException </PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">From
a design standpoint, things get really weird here. First of all, you might
think that because these methods are not part of a base class or the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Serializable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
interface, they ought to be defined in their own interface(s). But notice that
they are defined as 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which means they are to be called only by other members of this class. However,
you don&#8217;t actually call them from other members of this class, but
instead the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>writeObject(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>readObject(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ObjectOutputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ObjectInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects call your object&#8217;s 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>writeObject(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>readObject(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods. (Notice my tremendous restraint in not launching into a long diatribe
about using the same method names here. In a word: confusing.) You might wonder
how the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ObjectOutputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ObjectInputStream</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects have access to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods of your class. We can only assume that this is part of the
serialization magic.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
any event, anything defined in an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is automatically 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
so if 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>writeObject(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -