什么网站可以用手机做兼职赚钱,锦州哪家做网站,wordpress get_attached_media,公司网页制作模板图片最近发布了 有效的Java第三版 #xff0c;我一直对确定此类Java开发书籍的更新感兴趣#xff0c;该书籍的最新版本仅通过Java 6进行了介绍 。 在此版本中#xff0c;显然有与Java 7 #xff0c; Java 8和Java 9密切相关的全新项目#xff0c;例如第7章#xff08;“ Lamb… 最近发布了 有效的Java第三版 我一直对确定此类Java开发书籍的更新感兴趣该书籍的最新版本仅通过Java 6进行了介绍 。 在此版本中显然有与Java 7 Java 8和Java 9密切相关的全新项目例如第7章“ Lambda和流”中的项目42至48项目9“建议尝试使用资源”最终尝试”和第55条“明智地退还可选方案”。 我非常有点惊讶地发现 Effective Java第三版中有一个新项目并不是由Java的新版本专门驱动的而是由独立于Java版本的软件开发领域的开发驱动的。 第85条“ Java序列化的首选替代产品”是促使我写这篇介绍性文章的内容内容涉及将Google的Protocol Buffers与Java结合使用 。 Josh Bloch在“ 有效Java第三版”的条款 85中以粗体强调了以下两个与Java序列化有关的断言 “ 避免序列化攻击的最佳方法是永远不要反序列化任何东西。 “ “ 您没有理由在您编写的任何新系统中使用Java序列化。 “ 在概述了Java反序列化的危险并做出了这些大胆的声明之后Bloch建议Java开发人员使用他所谓的跨平台的结构化数据表示形式以避免在讨论Java时与术语“序列化”相关的混淆。 Bloch指出该类别中的领先产品是JSON JavaScript对象表示法 和协议缓冲区 protobuf 。 我发现提到协议缓冲区很有趣因为最近我一直在阅读和使用协议缓冲区。 在线全面介绍了JSON甚至Java的用法。 我觉得在Java开发人员中对协议缓冲区的了解可能比对JSON的了解要少因此有必要在Java上使用协议缓冲区。 Google的协议缓冲区在其项目页面上被描述为“一种不依赖语言不依赖平台的可序列化结构化数据的机制”。 该页面添加了“思考XML但更小更快更简单”。 尽管协议缓冲区的优点之一是它们支持以可被多种编程语言使用的方式表示数据但本文的重点仅在于将协议缓冲区与Java结合使用。 有许多与协议缓冲区相关的有用在线资源包括主项目页面 GitHub protobuf项目页面 proto3语言指南 也提供proto2语言指南 协议缓冲区基础Java教程 Java生成的代码指南 Java APIJavadoc文档 “ 协议缓冲区”发行页面和“ Maven存储库”页面 。 本文中的示例基于协议缓冲区3.5.1 。 协议缓冲区基础Java教程概述了将协议缓冲区与Java结合使用的过程。 与使用Java相比它涵盖了使用Java时要考虑的更多可能性和事情。 第一步是定义独立于语言的协议缓冲区格式。 这是在扩展名为.proto的文本文件中完成的。 对于我的示例我已经在下一个代码清单中显示的文件album.proto描述了我的协议格式。 原始专辑 syntax proto3;option java_outer_classname AlbumProtos;
option java_package dustin.examples.protobuf;message Album
{string title 1;repeated string artist 2;int32 release_year 3;repeated string song_title 4;
} 尽管上面对协议格式的定义很简单但其中有很多内容。 第一行明确指出我使用的是proto3而不是未明确指定时使用的默认默认proto2 。 仅当使用此协议格式生成Java代码时以option开头的两行才有意义它们指示最外层类的名称以及该最外层类的软件包该类将被生成以供Java应用程序使用此协议格式使用。 “ message”关键字表示此结构此处称为“专辑”需要表示。 此构造中有四个字段其中三个是string格式一个是整数 int32 。 四个字段中的两个在给定消息中可以不止一次存在因为它们用repeated保留字注释。 请注意我创建此定义时没有考虑Java除了两个option s它们指定了根据此格式规范生成Java类的详细信息。 所述album.proto上述未示出的文件需要被“编译”到Java源类文件 AlbumProtos.java在dustin.examples.protobuf包将允许写入和读出协议缓冲器的二进制格式的对应于定义的协议格式。 使用适当的基于操作系统的存档文件中包含的protoc编译器可以完成Java源代码文件的生成。 就我而言因为我正在Windows 10中运行此示例所以我下载并解压缩了protoc-3.5.1-win32.zip以便访问该protoc工具。 下一张图像使用命令protoc --proto_pathsrc --java_outdist\generated album.proto描述了我对album.proto运行protoc 。 对于运行上面的我有我的album.proto在文件src目录中指出--proto_path和我有一个创建但空目录下名为build\generated生成的Java源代码被放置在由按规定--java_out标志。 指定包中生成的类的Java源代码文件AlbumProtos.java有1000多行我不会在此处列出生成的类源代码但是可以在GitHub上找到 。 关于此生成的代码需要注意的几件有趣的事情是缺少导入语句完全合格的程序包名称代替了所有类引用。 Java生成的代码指南中提供了有关由protoc生成的Java源代码的更多详细信息。 重要的是要注意这个生成的类AlbumProtos仍然不受我自己的任何Java应用程序代码的影响并且仅由文章前面显示的album.proto文本文件生成。 有了可用于AlbumProtos的生成的Java源代码我现在将在其中生成该类的目录添加到IDE的源路径中因为现在将其视为源代码文件。 我也可以将其编译为.class或.jar用作库。 现在在我的源路径中有了这个生成的Java源代码文件我可以将其与自己的代码一起构建。 在继续本示例之前我们需要一个简单的Java类来用Protocol Buffers表示。 为此我将使用在下一个代码清单也在GitHub上提供 中定义的Album类。 相册.java package dustin.examples.protobuf;import java.util.ArrayList;
import java.util.List;/*** Music album.*/
public class Album
{private final String title;private final ListString artists;private final int releaseYear;private final ListString songsTitles;private Album(final String newTitle, final ListString newArtists,final int newYear, final ListString newSongsTitles){title newTitle;artists newArtists;releaseYear newYear;songsTitles newSongsTitles;}public String getTitle(){return title;}public ListString getArtists(){return artists;}public int getReleaseYear(){return releaseYear;}public ListString getSongsTitles(){return songsTitles;}Overridepublic String toString(){return title ( releaseYear ) by artists features songs songsTitles;}/*** Builder class for instantiating an instance of* enclosing Album class.*/public static class Builder{private String title;private ArrayListString artists new ArrayList();private int releaseYear;private ArrayListString songsTitles new ArrayList();public Builder(final String newTitle, final int newReleaseYear){title newTitle;releaseYear newReleaseYear;}public Builder songTitle(final String newSongTitle){songsTitles.add(newSongTitle);return this;}public Builder songsTitles(final ListString newSongsTitles){songsTitles.addAll(newSongsTitles);return this;}public Builder artist(final String newArtist){artists.add(newArtist);return this;}public Builder artists(final ListString newArtists){artists.addAll(newArtists);return this;}public Album build(){return new Album(title, artists, releaseYear, songsTitles);}}
} 在定义了Java“数据”类“ Album 并使用协议缓冲区生成的Java类可表示该专辑的情况下 AlbumProtos.java 我准备编写Java应用程序代码以“序列化”专辑信息而无需使用Java序列化。 该应用程序演示代码位于GitHub上可用的AlbumDemo类中 在本文中 我将重点AlbumDemo该类。 我们需要生成一个用于示例的Album实例并通过下一个硬编码列表来完成。 生成Album样本实例 /*** Generates instance of Album to be used in demonstration.** return Instance of Album to be used in demonstration.*/
public Album generateAlbum()
{return new Album.Builder(Songs from the Big Chair, 1985).artist(Tears For Fears).songTitle(Shout).songTitle(The Working Hour).songTitle(Everybody Wants to Rule the World).songTitle(Mothers Talk).songTitle(I Believe).songTitle(Broken).songTitle(Head Over Heels).songTitle(Listen).build();
} 协议缓冲区生成的类AlbumProtos类包括一个嵌套的AlbumProtos.Album类我将使用该类以二进制形式存储我的Album实例的内容。 下一个代码清单演示了如何完成此操作。 从Album实例化AlbumProtos.Album final Album album instance.generateAlbum();
final AlbumProtos.Album albumMessage AlbumProtos.Album.newBuilder().setTitle(album.getTitle()).addAllArtist(album.getArtists()).setReleaseYear(album.getReleaseYear()).addAllSongTitle(album.getSongsTitles()).build(); 如前面的代码清单所示“生成器”用于填充协议缓冲区生成的类的不可变实例。 参照该实例我现在可以使用该实例上的toByteArray()方法轻松地以Protocol Buffers二进制格式写出该实例的内容如下面的代码清单所示。 写作AlbumProtos.Album二进制形式 final byte[] binaryAlbum albumMessage.toByteArray(); 如下面的代码清单所示可以完成将byte[]数组读回Album实例的操作。 从AlbumProtos.Album二进制形式实例化Album /*** Generates an instance of Album based on the provided* bytes array.** param binaryAlbum Bytes array that should represent an* AlbumProtos.Album based on Google Protocol Buffers* binary format.* return Instance of Album based on the provided binary form* of an Album; may be {code null} if an error is encountered* while trying to process the provided binary data.*/
public Album instantiateAlbumFromBinary(final byte[] binaryAlbum)
{Album album null;try{final AlbumProtos.Album copiedAlbumProtos AlbumProtos.Album.parseFrom(binaryAlbum);final ListString copiedArtists copiedAlbumProtos.getArtistList();final ListString copiedSongsTitles copiedAlbumProtos.getSongTitleList();album new Album.Builder(copiedAlbumProtos.getTitle(), copiedAlbumProtos.getReleaseYear()).artists(copiedArtists).songsTitles(copiedSongsTitles).build();}catch (InvalidProtocolBufferException ipbe){out.println(ERROR: Unable to instantiate AlbumProtos.Album instance from provided binary data - ipbe);}return album;
} 如最后一个代码清单所示在调用生成的类中定义的static方法parseFrom(byte[])过程中可能引发检查异常InvalidProtocolBufferException 。 获得生成的类的“反序列化”实例本质上是一行其余几行从生成的类的实例中获取数据并将该数据设置在原始Album类的实例中。 演示类包括两行这些行打印出原始Album实例的内容以及最终从二进制表示形式检索到的实例。 这两行包括对两个实例的System.identityHashCode的调用以证明即使内容匹配它们也不是同一实例。 当使用前面显示的硬编码的Album实例详细信息执行此代码时输出如下所示 BEFORE Album (1323165413): Songs from the Big Chair (1985) by [Tears For Fears] features songs [Shout, The Working Hour, Everybody Wants to Rule the World, Mothers Talk, I Believe, Broken, Head Over Heels, Listen]AFTER Album (1880587981): Songs from the Big Chair (1985) by [Tears For Fears] features songs [Shout, The Working Hour, Everybody Wants to Rule the World, Mothers Talk, I Believe, Broken, Head Over Heels, Listen] 从此输出中我们看到两个实例中的相关字段相同并且两个实例确实是唯一的。 与使用Java的实现序列化接口的“近乎自动” 序列化机制相比这需要付出更多的努力但是与这种方法相关联的重要优势可以证明成本合理。 Josh Bloch在有效的Java第三版中讨论了Java默认机制中与反序列化相关的安全漏洞并断言“ 没有理由在编写的任何新系统中使用Java序列化。 ” 翻译自: https://www.javacodegeeks.com/2018/01/using-googles-protocol-buffers-java.html