中国建设银网站网站如何做绿标
web/
2025/10/1 10:06:19/
文章来源:
中国建设银网站,网站如何做绿标,北仑营销型网站制作,网站开发需要js 序列化内置对象本文是我们名为“ 高级Java ”的学院课程的一部分。 本课程旨在帮助您最有效地使用Java。 它讨论了高级主题#xff0c;包括对象创建#xff0c;并发#xff0c;序列化#xff0c;反射等。 它将指导您完成Java掌握的旅程#xff01; 在这里查看 #x… js 序列化内置对象 本文是我们名为“ 高级Java ”的学院课程的一部分。 本课程旨在帮助您最有效地使用Java。 它讨论了高级主题包括对象创建并发序列化反射等。 它将指导您完成Java掌握的旅程 在这里查看 目录 1.简介 2.可序列化的接口 3.可外部化的界面 4.有关可序列化接口的更多信息 5.可序列化和远程方法调用RMI 6. JAXB 7. JSON-P 8.序列化成本 9.超越Java标准库和规范 10.下一步是什么 11.下载源代码 1.简介 本教程的这一部分将专门用于序列化 将Java对象转换为可用于在同一或其他环境 http//en.wikipedia 中存储和稍后重构的格式的过程。 org / wiki / Serialization 。 序列化不仅允许将Java对象保存到持久性存储中或从持久性存储中加载Java对象而且还是现代分布式系统通信中非常重要的组件。 序列化并不容易但是有效的序列化则更加困难。 除了Java标准库之外还有许多可用的序列化技术和框架其中一些使用紧凑的二进制表示形式而另一些则将可读性放在首位。 尽管我们将在此过程中提及许多替代方案但我们的注意力将集中在Java标准库和最新规范中可Serializable 可Externalizable Serializable 用于XML绑定的Java体系结构 JAXB JSR-222 和用于Java的Java API。 JSON处理 JSON-P JSR-353 。 2.可序列化的接口 可以说Java中将类标记为可用于序列化的最简单方法是实现java.io.Serializable接口。 例如 public class SerializableExample implements Serializable {
} 序列化运行时与每个可序列化的类关联一个特殊的版本号称为序列号UID 在反序列化 与序列化相反的过程中使用该序列号 以确保已序列化对象的加载类兼容。 如果兼容性受到损害则将InvalidClassException 。 可序列化的类可以通过声明名称为serialVersionUID的字段为static final和long类型的字段来显式引入其自己的串行版本UID 。 例如 public class SerializableExample implements Serializable {private static final long serialVersionUID 8894f47504319602864L;
} 但是如果可序列化的类未明确声明serialVersionUID字段则序列化运行时将为该类生成一个默认的serialVersionUID字段。 值得一提的是所有实现Serializable类都强烈建议显式声明serialVersionUID字段因为默认的serialVersionUID生成严重依赖于内部类的详细信息并且可能会因Java编译器实现及其版本而有所不同。 这样为了保证行为的一致性可序列化的类必须始终声明一个显式的serialVersionUID字段。 一旦该类可序列化实现Serializable并声明serialVersionUID 就可以使用例如ObjectOutputStream / ObjectInputStream进行存储和检索 final Path storage new File( object.ser ).toPath();try( final ObjectOutputStream out new ObjectOutputStream( Files.newOutputStream( storage ) ) ) {out.writeObject( new SerializableExample() );
} 存储后可以通过类似的方式进行检索例如 try( final ObjectInputStream in new ObjectInputStream( Files.newInputStream( storage ) ) ) {final SerializableExample instance ( SerializableExample )in.readObject();// Some implementation here
} 如我们所见 Serializable接口没有对应该序列化什么以及如何进行序列化提供很多控制 transient关键字将字段标记为不可序列化除外。 而且它限制了更改内部类表示形式的灵活性因为它可能会破坏序列化/反序列化过程。 这就是为什么引入了另一个接口Externalizable原因。 3.可外部化的界面 与Serializable接口相反 Externalizable将类应如何序列化和反序列化的职责委托给该类。 它只有两种方法这是Java标准库中的声明 public interface Externalizable extends java.io.Serializable {void writeExternal(ObjectOutput out) throws IOException;void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
} 反过来每个实现Externalizable接口的类都应提供这两种方法的实现。 让我们看一个例子 public class ExternalizableExample implements Externalizable {private String str;private int number;private SerializableExample obj;Overridepublic void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {setStr(in.readUTF());setNumber(in.readInt());setObj(( SerializableExample )in.readObject());}Overridepublic void writeExternal(final ObjectOutput out) throws IOException {out.writeUTF(getStr());out.writeInt(getNumber());out.writeObject(getObj());}
} 与实现Serializable的类相似可以使用例如ObjectOutputStream / ObjectInputStream存储和检索实现Externalizable的类 final Path storage new File( extobject.ser ).toPath();final ExternalizableExample instance new ExternalizableExample();
instance.setStr( Sample String );
instance.setNumber( 10 );
instance.setObj( new SerializableExample() );try( final ObjectOutputStream out new ObjectOutputStream( Files.newOutputStream( storage ) ) ) {out.writeObject( instance );
}try( final ObjectInputStream in new ObjectInputStream( Files.newInputStream( storage ) ) ) {final ExternalizableExample obj ( ExternalizableExample )in.readObject();// Some implementation here
} 当使用Serializable接口的简单方法无法正常工作时 Externalizable接口允许进行细粒度的序列化/反序列化自定义。 4.有关可序列化接口的更多信息 在上一节中我们提到了Serializable接口并没有对应该序列化什么以及如何序列化提供很多控制。 实际上它并不是完全正确的至少在使用ObjectOutputStream / ObjectInputStream时。 任何可序列化的类都可以实现一些特殊方法以控制默认的序列化和反序列化。 private void writeObject(ObjectOutputStream out) throws IOException; 此方法负责为其特定类编写对象的状态以便相应的readObject方法可以将其还原可以通过调用out.defaultWriteObject调用保存对象字段的默认机制。 private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException; 此方法负责从流中读取并还原对象的状态可以通过调用in.defaultReadObject调用还原对象字段的默认机制。 private void readObjectNoData() throws ObjectStreamException; 在序列化流未将给定类列出为要反序列化的对象的超类的情况下此方法负责初始化对象的状态。 Object writeReplace() throws ObjectStreamException; 当可序列化的类需要指定将对象写入流时要使用的替代对象时使用此方法。 Object readResolve() throws ObjectStreamException; 最后当从流中读取可序列化的类的实例时可序列化的类需要指定替换时使用此方法。 一旦知道内在的实现细节和要使用的特殊方法默认的序列化机制使用Serializable接口在Java中就会变得非常麻烦。 您正在编写用于支持序列化的更多代码更有可能展示出更多的错误和漏洞。 但是有一种方法可以通过使用名为Serialization Proxy的非常简单的模式来降低这些风险该模式基于利用writeReplace和readResolve方法。 这种模式的基本思想是引入专用的伴随类进行序列化通常作为private static内部类它补充了需要序列化的类。 让我们看一下这个例子 public class SerializationProxyExample implements Serializable {private static final long serialVersionUID 6163321482548364831L;private String str;private int number; public SerializationProxyExample( final String str, final int number) {this.setStr(str);this.setNumber(number);}private void readObject(ObjectInputStream stream) throws InvalidObjectException {throw new InvalidObjectException( Serialization Proxy is expected );}private Object writeReplace() {return new SerializationProxy( this );}// Setters and getters here
} 对此类的实例进行序列化时类SerializationProxyExample实现将提供替换对象 SerializationProxy类的实例。 这意味着SerializationProxyExample类的实例将永远不会直接序列化和反序列化。 它还说明了为什么以某种方式进行反序列化尝试时 readObject方法会引发异常。 现在让我们看一下伴随的SerializationProxy类 private static class SerializationProxy implements Serializable {private static final long serialVersionUID 8368440585226546959L;private String str;private int number;public SerializationProxy( final SerializationProxyExample instance ) {this.str instance.getStr();this.number instance.getNumber();}private Object readResolve() {return new SerializationProxyExample(str, number); // Uses public constructor}
} 在我们的略微简化的情况下 SerializationProxy类只是复制了所有的领域SerializationProxyExample 但可能比被很多复杂。 因此当要反序列化此类的实例时 readResolve调用readResolve方法并且SerializationProxy提供替换这次的形式为SerializationProxyExample实例。 因此 SerializationProxy类可作为一个序列化代理SerializationProxyExample类。 5.可序列化和远程方法调用RMI 在相当长的一段时间内Java远程方法调用 RMI 是可用于在Java平台上构建分布式应用程序的唯一机制。 RMI提供了所有繁重的工作并且可以从同一主机或不同物理或虚拟主机上的其他JVM透明地调用远程Java对象的方法。 RMI的基础是对象序列化该对象序列化用于编组序列化和解组反序列化方法参数。 如今 RMI仍在许多Java应用程序中使用但由于它的复杂性和通信限制大多数防火墙都阻止RMI端口因此越来越少地选择RMI 。 要获取有关RMI的更多详细信息请参考官方文档 。 6. JAXB XML绑定的Java体系结构或者仅仅是JAXB 可能是Java开发人员可以使用的最古老的替代序列化机制。 在下面它使用XML作为序列化格式提供了广泛的自定义选项并包含许多注释这些注释使JAXB非常吸引人且易于使用注释在本教程的第5部分中介绍了如何以及何时使用Enums和注释 。 让我们看一下用JAXB注释注释的普通Java类POJO的简化示例 import java.math.BigDecimal;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;XmlAccessorType( XmlAccessType.FIELD )
XmlRootElement( name example )
public class JaxbExample {XmlElement(required true) private String str;XmlElement(required true) private BigDecimal number;// Setters and getters here
} 要使用JAXB基础结构将该类的实例序列化为XML格式唯一需要的是编组器或序列化器的实例例如 final JAXBContext context JAXBContext.newInstance( JaxbExample.class );
final Marshaller marshaller context.createMarshaller();final JaxbExample example new JaxbExample();
example.setStr( Some string );
example.setNumber( new BigDecimal( 12.33d, MathContext.DECIMAL64 ) );try( final StringWriter writer new StringWriter() ) {marshaller.marshal( example, writer );
} 这是上面示例中JaxbExample类实例的XML表示形式 ?xml version1.0 encodingUTF-8 standaloneyes?
examplestrSome string/strnumber12.33000000000000/number
/example 按照相同的原则可以使用解组器或反序列化器的实例将类的实例从XML表示反序列化回Java对象例如 final JAXBContext context JAXBContext.newInstance( JaxbExample.class );final String xml ?xml version\\1.0\\ encoding\\UTF-8\\ standalone\\yes\\? example strSome string/str number12.33000000000000/number /example;final Unmarshaller unmarshaller context.createUnmarshaller();
try( final StringReader reader new StringReader( xml ) ) {final JaxbExample example ( JaxbExample )unmarshaller.unmarshal( reader );// Some implementaion here
} 正如我们所看到的 JAXB易于使用并且XML格式在当今仍然很受欢迎。 但是XML的基本陷阱之一是冗长很多时候必要的XML结构元素大大超过了有效的数据有效负载。 7. JSON-P 自2013年以来借助新引入的JSON处理Java API JSON-P Java开发人员可以使用JSON作为序列化格式。 到目前为止尽管有很多讨论在即将发布的Java 9版本 http://openjdk.java.net/jeps/198 中将原生JSON支持包括到该语言中但JSON-P尚未成为Java标准库的一部分。 但是它在那里并且可以作为Java JSON处理参考实现 https://jsonp.java.net/ 的一部分使用。 与JAXB相比 无需为使它适合JSON序列化而向该类添加任何内容例如 public class JsonExample {private String str;private BigDecimal number;// Setters and getters here
} 序列化不像JAXB那样透明并且需要为要序列化为JSON的每个类编写一些代码例如 final JsonExample example new JsonExample();
example.setStr( Some string );
example.setNumber( new BigDecimal( 12.33d, MathContext.DECIMAL64 ) );try( final StringWriter writer new StringWriter() ) {Json.createWriter(writer).write( Json.createObjectBuilder().add(str, example.getStr() ).add(number, example.getNumber() ).build());
} 这是上面示例中JsonExample类实例的JSON表示形式 {str:Some string,number:12.33000000000000
} 反序列化过程也是如此 final String json {\\str\\:\\Some string\\,\\number\\:12.33000000000000}; try( final StringReader reader new StringReader( json ) ) {final JsonObject obj Json.createReader( reader ).readObject();final JsonExample example new JsonExample();example.setStr( obj.getString( str ) );example.setNumber( obj.getJsonNumber( number ).bigDecimalValue() );
} 可以说目前Java中的JSON支持非常基本。 尽管如此拥有一个很棒的东西并且Java社区正在通过引入用于JSON绑定的Java API JSON-B JSR-367 来努力丰富JSON支持。 使用此API与JSON之间的Java对象序列化和反序列化应该像JAXB一样透明。 8.序列化成本 重要的是要理解尽管序列化/反序列化在Java中看起来很简单但它不是免费的并且取决于数据模型和数据访问模式可能会消耗大量的网络带宽内存和CPU资源。 不仅如此尽管如此Java对可序列化类提供了某种版本支持使用序列化UID正如我们在“可序列化接口 ”一节中所看到的它确实使开发过程变得更加困难因为开发人员需要自己弄清楚如何管理数据模型的演变。 另外要说明的是Java序列化在JVM领域之外无法正常工作。 对于使用多种编程语言和运行时构建的现代分布式应用程序这是一个重要的限制。 这就解释了为什么许多替代的序列化框架和解决方案应运而生并成为Java生态系统中非常流行的选择。 9.超越Java标准库和规范 在本节中我们将从Fast-serialization项目 http://ruedigermoeller.github.io/fast-serialization/ 开始研究无痛且有效的Java序列化的替代解决方案快速替换Java序列化。 快速序列化的用法与Java标准库提供的用法没有太大不同但声称它更快更有效。 另一组框架对此问题有不同的看法。 它们基于结构化数据定义或协议并将数据序列化为紧凑的二进制表示形式甚至可以从定义中生成相应的数据模型。 除此之外这些框架远远超出了Java平台可以用于跨语言/跨平台序列化。 该领域中最知名的Java库是Google协议缓冲区 https://developers.google.com/protocol-buffers/Apache Avro http://avro.apache.org/ 和Apache Thrift https/ /thrift.apache.org/ 。 10.下一步是什么 在本教程的这一部分中我们讨论了Java语言及其运行时提供的内置序列化技术。 我们已经看到了当今的串行化的重要性当时几乎所有正在构建的单个应用程序都是大型分布式系统的一部分并且需要与其余部分或与其他外部系统进行通信。 在本教程的下一部分中我们将讨论Java中的反射和动态语言支持。 11.下载源代码 您可以在这里下载本课程的源代码 advanced-java-part-10 翻译自: https://www.javacodegeeks.com/2015/09/built-in-serialization-techniques.htmljs 序列化内置对象
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/84989.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!