J2SE中的序默认序列化_MySQL
J2SE
要保存的也被保存了下来。一般情况下,我们仅仅需要保存逻辑数据就可以了。不需要保存的数据我们可以用关键字transient标出。
以下是一个例子:
import java.io.*;
public class Serial implements Serializable {
int company_id;
String company_addr;
transient boolean company_flag;
}
则company_flag字段将不会参与序列化与反序列化,但同时你也增加了为他初始值的责任。这也是序列化常常导致的问题之一。因为序列化相当于一个只接受数据流的public构造函数,这种对象构造方法是语言之外的。但他仍然是一种形式上的构造函数。如若你的类不能够通过其他方面来保证初始化,则你需要额外的提供readObject方法,首先正常的反序列化,然后对transient标示的字段进行初始化。
在不适合的时候,使用java默认的序列化行为可能会带来速度上的影响,最糟糕的情况是,可能导致溢出。在某些数据结构的实现中,经常会充斥着各种的循环引用,而java的默认序列化行为,并不了解你的对象结构,其结果就是java试图通过一种昂贵的“图遍历”来保存对象状态。可想而知,不但慢而且可能溢出。这时候你就要提供自己的readObject,来代替默认的行为。
兼容性问题
兼容性历来是复杂而麻烦的问题。
不要兼容性:
首先来看看如果我们的目的是不要兼容性,应该注意哪些。不要兼容性的场合很多,比如war3每当版本升级就不能够读取以前的replays。
兼容也就是版本控制,java通过一个名为UID(stream unique identifier)来控制,这个UID是隐式的,它通过类名,方法名等诸多因素经过计算而得,理论上是一一映射的关系,也就是唯一的。如果UID不一样的话,就无法实现反序列化了,并且将会得到InvalidClassException。
当我们要人为的产生一个新的版本(实现并没有改动),而抛弃以前的版本的话,可以通过显式的声名UID来实现:
private static final long serialVersionUID=????;
你可以编造一个版本号,但注意不要重复。这样在反序列化的时候老版本将得到InvalidClassException,我们可以在老版本的地方捕捉这个异常,并提示用户升级的新的版本。
当改动不大时,保持兼容性(向下兼容性的一个特例):
有时候你的类增加了一些无关紧要的非私有方法,而逻辑字段并不改变的时候,你当然希望老版本和新版本保持兼容性,方法同样是通过显式的声名UID来实现。下面我们验证一下。
老版本:
import java.io.*;
public class Serial implements Serializable {
int company_id;
String company_addr;
public Serial1(int company_id, String company_addr) {
this.company_id = company_id;
this.company_addr = company_addr;
}
public String toString() {
return "DATA: "+company_id+" "+
company_addr;
}
}
新版本
import java.io.*;
public class Serial implements Serializable {
int company_id;
String company_addr;
public Serial1(int company_id, String company_addr) {
this.company_id = company_id;
this.company_addr = company_addr;
}
public String toString() {
return "DATA: "+company_id+" "+ company_addr;
}
public void todo(){}//无关紧要的方法
}
首先将老版本序列化,然后用新版本读出,发生错误:
java.io.InvalidClassException: Serial.Serial1; local class incompatible: stream classdesc serialVersionUID = 762508508425139227, local class serialVersionUID = 1187169935661445676
接下来我们加入显式的声名UID:
private static final long serialVersionUID=762508508425139227l;
再次运行,顺利地产生新对象
DATA: 1001 com1
如何保持向上兼容性:
向上兼容性是指老的版本能够读取新的版本序列化的数据流。常常出现在我们的服务器的数据更新了,仍然希望老的客户端能够支持反序列化新的数据流,直到其更新到新的版本。可以说,这是半自动的事情。
跟一般的讲,因为在java中serialVersionUID是唯一控制着能否反序列化成功的标志,只要这个值不一样,就无法反序列化成功。但只要这个值相同,无论如何都将反序列化,在这个过程中,对于向上兼容性,新数据流中的多余的内容将会被忽略;对于向下兼容性而言,旧的数据流中所包含的所有内容都将会被恢复,新版本的类中没有涉及到的部分将保持默认值。利用这一特性,可以说,只要我们认为的保持serialVersionUID不变,向上兼容性是自动实现的。
当然,一但我们将新版本中的老的内容拿掉,情况就不同了,即使UID保持不变,会引发异常。正是因为这一点,我们要牢记一个类一旦实现了序列化又要保持向上下兼容性,就不可以随随便便的修改了!!!
测试也证明了这一点,有兴趣的读者可以自己试一试。
如何保持向下兼容性:
一如上文所指出的,你会想当然的认为只要保持serialVersionUID不变,向下兼容性是自动实现的。但实际上,向下兼容要复杂一些。这是因为,我们必须要对那些没有初始化的字段负责。要保证它们能被使用。
所以必须要利用
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException{
in.defaultReadObject();//先反序列化对象
if(ver=5552){
//以前的版本5552
…初始化其他字段
}else if(ver=5550){
//以前的版本5550
…初始化其他字段
}else{
//太老的版本不支持
throw new InvalidClassException();
}
}
细心的读者会注意到要保证in.defaultReadObject();能够顺利执行,就必须要求serialVersionUID保持一致,所以这里的ver不能够利用serialVersionUID了。这里的ver是一个我们预先安插好的final long ver=xxxx;并且它不能够被transient修饰。所以保持向下的兼容性至少有三点要求:
1.serialVersionUID保持一致
2.预先安插好我们自己的版本识别标志的final long ver=xxxx;
3.保证初始化所有的域
讨论一下兼容性策略:
到这里我们可以看到要保持向下的兼容性很麻烦。而且随着版本数目的增加。维护会变得困难而繁琐。讨论什么样的程序应该使用怎么样的兼容性序列化策略已经超出本文的范畴,但是对于一个游戏的存盘功能,和对于一个字处理软件的文档的兼容性的要求肯定不同。对于rpg游戏的存盘功能,一般要求能够保持向下兼容,这里如果使用java序列化的方法,则可根据以上分析的三点进行准备。对于这样的情况使用对象序列化方法还是可以应付的。对于一个字处理软件的文档的兼容性要求颇高,一般情况下的策略都是要求良好的向下兼容性,和尽可能的向上兼容性。则一般不会使用对象序列化技术,一个精心设计的文档结构,更能解决问题。
数据一致性问题、约束问题
要知道序列化是另一种形式上的“public构造函数”,但他仅仅构造起对象,而不作任何的检查,这样人很不舒服,所以必要的检查是必须的,这利用了readObject()
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException{
in.defaultReadObject();//先反序列化对象
…进行检查与初始化
}
出于结构化的考虑,通常使用一个名为initialize的函数,负责检查与初始化,如果失败抛出异常。要保持检查与初始化是很容易被忘记的,这常常导致问题。另一个问题在于当父类没有加入readObject()的时候,子类很容易忘记要调用对应的initialize函数。这仿佛回到了当初为什么要引入构造函数的问题,原因就是防止子类忘记调用初始化函数引发各种问题。所以,如果要保持数据一致性,一定要加入readObject()。
安全问题
安全性的话题超出了本文的范畴,但是你应该要知道,有可能一个攻击者会对你的类准备一个恶意的数据流企图生成一个错误的类。当你需要确保你的对象数据安全的话,你一般可以利用上面的方法来检查,并初始化,但对于某些引用不好检查。解决方法就是对重要的部件进行保护性拷贝。这里推荐一个好方法,它不用保护性拷贝个别的域,而是直接保护性拷贝整个对象。这就是:
Object readResolve() throws ObjectStreamException;
这个方法的用途就是,他会紧接着readObject()调用。它将会利用返回的对象代替原来反序列化的对象。也就是原来readObject()反序列化的对象将会被立即的丢弃。
Object readResolve() throws ObjectStreamException{
return new Serial2(this.xxx1,this.xxx2);// xxx1、xxx2是刚刚反序列化得来的,这是一种保护性拷贝
}
这样的话虽然在时间上有所浪费,但是对于特别的重要而安全的类,可以使用这种方法。如果数据一致性问题、约束问题通过逐一检查来解决很麻烦,也可以利用这种方法,但要考虑好成本,和注意下面的局限性。 利用readResolve()有一个明显的缺点,就是当父类实现了readResolve(),子类将变得无丛下手。如果一个保护的或者是公有的父类的readResolve()存在,并且子类也没有改写它,将会使得子类反序列化的时候最终得到一个父类的对象,这既不是我们要得结果,也不容易发现这种错误。而让子类重写readResolve()无疑是一个负担。也就是说对于要继承的类而言,实现readResolve()来保护类不是一个好方法。我们只能利用第一种方法写一个保护性的readObject()。
所以我的建议是:一般情况下,只有对于final的类采用readResolve()来进行保护。

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Um die Curl-Version unter Linux zu aktualisieren, können Sie die folgenden Schritte ausführen: Überprüfen Sie die aktuelle Curl-Version: Zunächst müssen Sie die im aktuellen System installierte Curl-Version ermitteln. Öffnen Sie ein Terminal und führen Sie den folgenden Befehl aus: curl --version Dieser Befehl zeigt die aktuellen Informationen zur Curl-Version an. Verfügbare Curl-Version bestätigen: Bevor Sie Curl aktualisieren, müssen Sie die neueste verfügbare Version bestätigen. Sie können die offizielle Website von Curl (curl.haxx.se) oder verwandte Softwarequellen besuchen, um die neueste Version von Curl zu finden. Laden Sie den Curl-Quellcode herunter: Laden Sie mit Curl oder einem Browser die Quellcodedatei für die Curl-Version Ihrer Wahl herunter (normalerweise .tar.gz oder .tar.bz2).

In einer Minute erledigt: So aktualisieren Sie die Pip-Version. Mit der rasanten Entwicklung von Python ist Pip zu einem Standardtool für die Python-Paketverwaltung geworden. Mit der Zeit werden die Pip-Versionen jedoch ständig aktualisiert. Um die neuesten Funktionen nutzen und mögliche Sicherheitslücken schließen zu können, ist es sehr wichtig, die Pip-Version zu aktualisieren. In diesem Artikel wird erläutert, wie Sie Pip in einer Minute schnell aktualisieren können, und es werden spezifische Codebeispiele bereitgestellt. Zuerst müssen wir ein Befehlszeilenfenster öffnen. In Windows-Systemen können Sie verwenden

Überprüfen der Kylin-Betriebssystemversion und der Kernelversion Im Kirin-Betriebssystem ist das Wissen, wie die Systemversion und die Kernelversion überprüft werden, die Grundlage für die Systemverwaltung und -wartung. Methode 1 zum Überprüfen der Kylin-Betriebssystemversion: Verwenden Sie die Datei /etc/.kyinfo. Um die Kylin-Betriebssystemversion zu überprüfen, können Sie die Datei /etc/.kyinfo überprüfen. Diese Datei enthält Informationen zur Betriebssystemversion. Führen Sie den folgenden Befehl aus: cat/etc/.kyinfo Dieser Befehl zeigt detaillierte Versionsinformationen des Betriebssystems an. Methode 2: Verwenden Sie die Datei /etc/issue. Eine andere Möglichkeit, die Betriebssystemversion zu überprüfen, besteht darin, sich die Datei /etc/issue anzusehen. Diese Datei enthält auch Versionsinformationen, ist jedoch möglicherweise nicht so gut wie die .kyinfo-Datei

Die Bedeutung und der Unterschied der PHP-Version NTS PHP ist eine beliebte serverseitige Skriptsprache, die im Bereich der Webentwicklung weit verbreitet ist. Es gibt zwei Hauptversionen von PHP: ThreadSafe (TS) und Non-ThreadSafe (NTS). Auf der offiziellen Website von PHP können wir zwei verschiedene PHP-Download-Versionen sehen, nämlich PHPNTS und PHPTS. Was bedeutet also die PHP-Version NTS? Was ist der Unterschied zur TS-Version? Nächste,

Um die installierte Version von Oracle einfach zu überprüfen, sind spezifische Codebeispiele erforderlich. Da es sich bei der Oracle-Datenbank um eine in Datenbankverwaltungssystemen auf Unternehmensebene weit verbreitete Software handelt, gibt es viele Versionen und unterschiedliche Installationsmethoden. In unserer täglichen Arbeit müssen wir häufig die installierte Version der Oracle-Datenbank auf entsprechende Betriebs- und Wartungsarbeiten überprüfen. In diesem Artikel erfahren Sie, wie Sie die installierte Version von Oracle einfach überprüfen können, und geben konkrete Codebeispiele. Methode 1: Durch SQL-Abfrage in der Oracle-Datenbank können wir

Zu Llama3 wurden neue Testergebnisse veröffentlicht – die große Modellbewertungs-Community LMSYS veröffentlichte eine große Modell-Rangliste, die Llama3 auf dem fünften Platz belegte und mit GPT-4 den ersten Platz in der englischen Kategorie belegte. Das Bild unterscheidet sich von anderen Benchmarks. Diese Liste basiert auf Einzelkämpfen zwischen Modellen, und die Bewerter aus dem gesamten Netzwerk machen ihre eigenen Vorschläge und Bewertungen. Am Ende belegte Llama3 den fünften Platz auf der Liste, gefolgt von drei verschiedenen Versionen von GPT-4 und Claude3 Super Cup Opus. In der englischen Einzelliste überholte Llama3 Claude und punktgleich mit GPT-4. Über dieses Ergebnis war Metas Chefwissenschaftler LeCun sehr erfreut und leitete den Tweet weiter

Warum ist Python so beliebt? Der Grund ist einfach: Es ist leicht zu erlernen, einfach zu bedienen und schnell anzuwenden, sodass es auch für Anfänger geeignet ist. Egal um welches Projekt es sich handelt, solange es um Programmierung geht, ist Python oft meine erste Wahl. Darüber hinaus müssen Sie nicht bei Linux-Systemen bleiben, Windows kann es auch gut unterstützen. Ich habe Python auf meinem Windows 11-Betriebssystem installiert und verwende es oft, um Programme zu schreiben und Code auszuführen. Die Installation von Python unter Windows ist sehr einfach. Als Nächstes werde ich zwei gängige Installationsmethoden vorstellen. Wählen Sie die entsprechende Python-Version. Es ist sehr wichtig, die richtige Version auszuwählen. Dies hängt mit der Kompatibilität und Funktionalität des Programms zusammen: Die aktuellen Versionen umfassen Python2 und

Die DP-Schnittstelle ist ein wichtiges Schnittstellenkabel im Computer. Viele Benutzer möchten wissen, wie sie überprüfen können, ob die DP-Schnittstelle 1.2 oder 1.4 ist. Tatsächlich müssen sie sie nur in GPU-Z überprüfen. So ermitteln Sie, ob die dp-Schnittstelle 1.2 oder 1.4 ist: 1. Wählen Sie zunächst „Erweitert“ in GPU-Z. 2. Schauen Sie sich „Monitor1“ in „Allgemein“ unter „Erweitert“ an, dort sehen Sie die beiden Punkte „LinkRate (aktuell)“ und „Lanes (aktuell)“. 3. Wenn schließlich 8,1 Gbit/s × 4 angezeigt wird, bedeutet dies DP1.3-Version oder höher, normalerweise DP1.4. Wenn es 5,4 Gbit/s × 4 ist
