天道酬勤,学无止境

使用不同的程序包名称在不同的应用程序中反序列化Java对象(de/serialize java objects across different applications using different package names)

问题

我想在不同的应用程序之间共享Java对象。

只要我在不同项目中使用相同的程序包名称,它就可以正常工作。 但是,如果我更改程序包名称,它将不再起作用。

我试图通过扩展ObjectInputStream类并覆盖readClassDescriptor方法来解决此问题。

但是这样做会导致以下错误:

java.io.StreamCorruptedException: invalid type code: 00

...不知道如何解决这个问题。

这是我用于扩展ObjectInputStream类的代码:

public class MyObjectInputStream extends ObjectInputStream {

    public static Map<String, Class> classNameMapping = initclassNameMapping(); 

    private static Map<String, Class> initclassNameMapping(){
        Map<String, Class> res = new HashMap<String, Class>();
        //ipxTest is the name of the package where the objects got serialized
        res.put("ipxTest.IPX", interprojectxchangeTest.IPX.class); 
        res.put("ipxTest.A", interprojectxchangeTest.A.class);
        return Collections.unmodifiableMap(res);
    }

    public MyObjectInputStream(InputStream in) throws IOException {
        super(in);
        enableResolveObject(true);
    }


    protected MyObjectInputStream() throws IOException, SecurityException {
        super();
        enableResolveObject(true);
    }

    @Override
    protected java.io.ObjectStreamClass readClassDescriptor() 
            throws IOException, ClassNotFoundException {
        ObjectStreamClass desc = super.readClassDescriptor();
        if (classNameMapping.containsKey(desc.getName()))
            return ObjectStreamClass.lookup(classNameMapping.get(desc.getName()));
        return desc;
    }
}

IPX和A类在不同的项目中看起来都相同,并且具有相同的serialID。

回答1

我的第一个建议是简化您的实现并停止使用框架-在应用程序中使用相同的程序包名称。 我建议用可序列化的类制作一个库,并在实现之间共享。

如果必须在具有不同程序包名称的应用程序之间进行序列化/反序列化,那么我的建议是放弃与类名和程序包名称紧密相关的内置Java序列化,并使用类似Gson的序列化/反序列化。

Gson允许您指定TypeAdaper。 您可以为要序列化/反序列化的每个类创建并注册一个TypeAdapter,并在序列化时将类名(不带包名)指定为“类型”,如以下示例所示,但是使用getSimpleName()而不是getCanonicalName( )

反序列化时,您必须在“类型”中添加正确的包名称

您必须为每个应用程序单独进行TypeAdapters。

public class GsonTypeAdapter<T> implements JsonSerializer<T>, JsonDeserializer<T> {
    @Override
    public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject result = new JsonObject();
        result.add("type", new JsonPrimitive(src.getClass().getCanonicalName()));
        result.add("properties", context.serialize(src, src.getClass()));

        return result;
    }

    @Override
    public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
        throws JsonParseException {
        JsonObject jsonObject = json.getAsJsonObject();
        String type = jsonObject.get("type").getAsString();
        JsonElement element = jsonObject.get("properties");

        try {
            return context.deserialize(element, Class.forName(type));
        } catch (ClassNotFoundException cnfe) {
            throw new JsonParseException("Unknown element type: " + type, cnfe);
        }
    }
}
回答2

类的Package名称是其全名的基本部分。

如果matthiasboesinger是您的名字,那么matthias只是您的名字,可以识别您,但是boesinger部分是您唯一的名称标识符。

类似地,在类中,编译器使用其完整名称而不只是名字来标识类及其序列化对象。

如果您更改了程序包名称,则会丢失类的完整性,因为不同的类可以存在于具有相同名称的不同程序包中。

因此,您正在尝试的事情是不可能的。

除非您编写一个适配器类,该适配器类从具有包名的原始类中拾取数据,然后将数据泵入新的包名类。

但是那只是在灌木丛中跳动。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 无法将MyObject类型的对象强制转换为MyObject类型(Unable to cast object of type MyObject to type MyObject)
    问题 在这种情况下,我在C#中使用的Web服务方法返回一个业务对象,当使用以下代码调用该Web服务方法时,在reference.cs类中出现了异常“无法将ContactInfo类型的对象转换为ContactInfo类型”网络参考 代码: ContactInfo contactInfo = new ContactInfo(); Contact contact = new Contact(); contactInfo = contact.Load(this.ContactID.Value); 任何帮助将非常感激。 回答1 这是因为ContactInfo对象之一是Web服务代理,并且位于不同的名称空间中。 这是asmx样式的Web服务的已知问题。 过去,我已经实现了自动浅表复制来解决此问题(这是方法,尽管如果我再次进行此操作,我可能会改用AutoMapper)。 例如,如果您的装配具有以下类: MyProject.ContactInfo 然后从Web方法返回它的一个实例: public class DoSomethingService : System.Web.Services.WebService { public MyProject.ContactInfo GetContactInfo(int id) { // Code here... } } 然后
  • Java枚举-为什么使用toString而不是name(Java enum - why use toString instead of name)
    问题 如果您在方法name()的枚举api中查看,则会显示: 返回此枚举常量的名称,该名称与在其枚举声明中所声明的完全相同。 大多数程序员应该优先使用toString方法,因为toString方法可能返回更用户友好的名称。 此方法主要设计用于在特殊情况下正确性取决于获得确切名称的特定情况,具体名称在发行版本之间不会有所不同。 为什么最好使用toString() ? 我的意思是当name()已经是final时,toString可能会被覆盖。 因此,如果您使用toString并且有人重写它以返回硬编码值,则整个应用程序都将关闭...同样,如果您在源代码中查找,则toString()方法将完全返回名称。 这是同一件事。 回答1 这实际上取决于您要对返回值执行的操作: 如果需要获取用于声明枚举常量的确切名称,则应使用name()因为toString可能已被覆盖如果要以用户友好的方式打印枚举常量,则应使用toString ,它可能已被覆盖(或不被覆盖!)。 当我觉得这可能令人困惑时,我提供了一个更具体的getXXX方法,例如: public enum Fields { LAST_NAME("Last Name"), FIRST_NAME("First Name"); private final String fieldDescription; private Fields(String
  • 无法在Spring 3 REST Web服务中从START_ARRAY令牌中反序列化对象的实例(Cannot deserialize instance of object out of START_ARRAY token in Spring 3 REST Webservice)
    问题 我正在利用Spring提供的这个很酷的功能:Spring RESTWebService(spring的版本为3)。 如果我从浏览器访问URL,则可以看到JSON响应,但是可以从客户端端点(Android应用程序)看到以下错误消息: Caused by: org.springframework.web.client.ResourceAccessException: I/O error: Can not deserialize instance of MyObject out of START_ARRAY token at [Source: org.apache.http.conn.EofSensorInputStream@4076e940; line: 1, column: 1]; nested exception is org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of MyObject out of START_ARRAY token at [Source: org.apache.http.conn.EofSensorInputStream@4076e940; line: 1, column: 1] at org.springframework.web.client
  • 什么是对象序列化?(What is object serialization?)
    问题 “对象序列化”是什么意思? 你能用一些例子解释一下吗? 回答1 序列化是将对象转换为一系列字节,以便可以将对象轻松保存到持久性存储中或通过通信链接进行流传输。 然后可以将字节流反序列化-转换为原始对象的副本。 回答2 您可以将序列化视为将对象实例转换为字节序列(取决于实现的二进制或非二进制)的过程。 当您要通过网络传输一个对象数据(例如从一个JVM传输到另一个JVM)时,此功能非常有用。 在Java中,平台内置了序列化机制,但是您需要实现Serializable接口才能使对象可序列化。 您也可以通过将属性标记为transient来防止对象中的某些数据被序列化。 最后,您可以覆盖默认机制,并提供自己的机制。 在某些特殊情况下,这可能是合适的。 为此,您可以使用Java中的隐藏功能之一。 重要的是要注意,序列化的是对象的“值”或内容,而不是类定义。 因此,方法未序列化。 这是一个非常基本的示例,带有注释以方便阅读: import java.io.*; import java.util.*; // This class implements "Serializable" to let the system know // it's ok to do it. You as programmer are aware of that. public class
  • 什么是serialVersionUID,为什么要使用它?(What is a serialVersionUID and why should I use it?)
    问题 当缺少serialVersionUID时,Eclipse会发出警告。 可序列化的类Foo没有声明类型为long的静态最终serialVersionUID字段 什么是serialVersionUID ,为什么重要? 请显示一个示例,其中缺少serialVersionUID会导致问题。 回答1 您将得到有关java.io.Serializable的文档很好的解释: 序列化运行时与每个可序列化的类关联一个版本号,称为serialVersionUID ,在反序列化期间使用该版本号来验证序列化对象的发送者和接收者是否已加载了该对象的与序列化兼容的类。 如果接收者已为该对象加载了一个与相应发送者类具有不同的serialVersionUID的类,则反序列化将导致InvalidClassException。 可序列化的类可以通过声明一个名为serialVersionUID的字段来显式声明其自己的serialVersionUID ,该字段必须是静态的,最终的且类型为long : ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L; 如果可序列化的类未显式声明serialVersionUID ,则序列化运行时将根据该类的各个方面,为该类计算默认的serialVersionUID值,如Java(TM)对象序列化规范中所述。 但是
  • 为什么没有自动生成serialVersionUID?(Why isn't the serialVersionUID automatically generated?)
    问题 为什么没有自动生成serialVersionUID ? 我在应用程序服务器上遇到了一个问题,该服务器显然正在缓存旧的类。 回答1 不会自动生成serialversionuid,因为这很危险。 设置serialversionuid时,这意味着一个类的两个版本在序列化方面是兼容的。 假设您有一个名为Foo的类,并且它没有serialversionuid (默认值),并且将Foo的实例序列化为文件。 稍后,您将一些新成员添加到Foo类。 如果尝试从文件中反序列化Foo对象,则会出现序列化失败,指出对象不兼容。 他们是不兼容的,这是你想要的,这是默认。 它们不兼容,因为无法从Foo的旧序列化实例初始化Foo类中的新成员。 现在,您可能会说:“我不在乎,在我的应用程序中,可以将那些字段初始化为可接受的”。 如果确实如此,则可以将新Foo类的serialversionuid设置为与旧Foo类相同。 这将告诉Java这些对象在可序列化方面是兼容的,并且当您将旧的Foo实例反序列化为新的Foo类时,Java将不会抱怨(但是新字段仍将未初始化)。 如果您是第一次创建新类,并且设置了serialversionuid,则您正在输入合同。 该合同是, “对于具有相同serialversionuid的此类的所有将来版本,我将保证它们在状态和序列化方面都是兼容的” 。 如果更改了一个类
  • 如何从osgi中的字节反序列化对象(How do you deserialize an object from bytes in osgi)
    问题 在我的osgi应用程序中,我有三个捆绑包travel.api , table.api和utils 。 travel.api取决于table.api ,后者取决于utils 。 请注意, travel.api不直接依赖utils 。 我使用aQute Bnd生成清单,并且我相信它工作正常。 清单如下所示。 有一个名为PageData的类,它具有一个TableData类型的字段,而该字段又具有一个TestObject类型的字段。 PageData位于travel.api , TableData位于table.api而TestObject位于utils 。 装入捆绑包时,所有这些都可以正常工作。 当我收到代表PageData对象的字节数组时,就会出现问题。 我必须在travel.api捆绑包中反序列化它。 这不应该是问题,因为它是在这里定义的。 我使用org.jboss.netty.handler.codec.serialization.ObjectDecoderInputStream并从travel.api捆绑包中传入类加载器。 抛出以下所示的异常,但基本上说: Caused by: java.lang.ClassNotFoundException: com.openaf.utils.TestObject not found by travel.api [9]. 现在这很有意义
  • 1-Java 的关键字及保留字(个人学习笔记)
    Java 的关键字及保留字 内容来自网络搜集整理 图片原文链接:https://blog.csdn.net/z1web/article/details/89068217 个人不熟悉的关键字学习笔记: 一、native ​ 参考链接:https://blog.csdn.net/funneies/article/details/8949660?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id=1328760.1071.16171808089191777&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control ​ 参考链接:https://blog.csdn.net/bifuguo/article/details/81513526。 ​ native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如 C和C++)实现的文件中
  • Java关键字整理/理解
    Java 关键字及保留字 java关键字的整理以及解释 java关键字整理 如图: java关键字的整理以及解释 一,native   native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。   JNI是Java本机接口(Java Native Interface),是一个本机编程接口,它是Java软件开发工具箱(Java Software Development Kit,SDK)的一部分。JNI允许Java代码使用以其他语言编写的代码和代码库。Invocation API(JNI的一部分)可以用来将Java虚拟机(JVM)嵌入到本机应用程序中,从而允许程序员从本机代码内部调用Java代码。   不过,对Java外部的调用通常不能移植到其他平台,在applet中还可能引发安全异常。实现本地代码将使您的Java应用程序无法通过100%纯Java测试。 Native可以和其他一些修饰符连用,但是abstract方法和Interface方法不能用native来修饰。   ​ 可以将native方法比作Java程序同C程序的接口,其实现步骤: ​ 1)在Java中声明native()方法,然后编译;  ​ 2
  • 2021最新100道Java面试题!【附答案解析和思维导图总结】
    前言 关于Java知识点总结了一个思维导图分享给大家,希望对大家有多帮助! 文章目录 常见的Java问题 Java线程(附思维导图、答案解析) Java集合类(附答案解析) 垃圾收集器(Garbage Collectors) 异常处理(附答案解析) Java小应用程序(Applet)(附答案解析) Swing(附答案解析) JDBC(附答案解析) Servlet(附答案解析) 1000道互联网大厂Java工程师面试题 Java是一个支持并发、基于类和面向对象的计算机编程语言。下面列出了面向对象软件开发的优点: 代码开发模块化,更易维护和修改。代码复用。增强代码的可靠性和灵活性。增加代码的可理解性。 面向对象编程有很多重要的特性,比如:封装,继承,多态和抽象。下面的章节我们会逐个分析这些特性。 封装 封装给对象提供了隐藏内部特性和行为的能力。对象提供一些能被其他对象访问的方法来改变它内部的数据。在Java当中,有3种修饰符:public,private和protected。每一种修饰符给其他的位于同一个包或者不同包下面对象赋予了不同的访问权限。 下面列出了使用封装的一些好处: 通过隐藏对象的属性来保护对象内部的状态。提高了代码的可用性和可维护性,因为对象的行为可以被单独的改变或者是扩展。禁止对象之间的不良交互提高模块化。 参考这个文档获取更多关于封装的细节和示例。 多态
  • 在没有名称空间的情况下反序列化XML,但在需要名称空间的类中反序列化XML(Deserialize XML without namespaces but in a class expecting namespaces)
    问题 复制: 序列化对象时忽略所有xml名称空间吗? 不一样..我想换一种方式:反序列化! 我有一个C#类,如下所示: [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.portalfiscal.inf.br/nfe")] [System.Xml.Serialization.XmlRootAttribute("NFe", Namespace = "http://www.portalfiscal.inf.br/nfe", IsNullable = false)] public partial class TNFe { private TNFeInfNFe infNFeField; private SignatureType signatureField; /// <remarks
  • 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文
    前言 在网上一搜索Java学习会弹出无数文章,但全都是培训机构的大纲文,实在鸡肋,根本没写一个字是在帮助菜鸟怎么认识Java的,所以我琢磨着写一篇真正意义上的Java从0到1的文章,帮0基础的小白和初学的财年打开Java的大门 如果观察过招聘网站上的Java相关岗位需求就会发现,抛开其它的经验能力等等,单纯从技术,或者说知识上来讲,可以发现一些共通的地方。 Java基础 计算机基础 数据库,SQL/NoSQL 常用开源框架 分布式/微服务 中间件,缓存、消息中间件 学习任何一门编程语言,首先要学习的是基础语法,开启Java学习的第一步,当然就是深入掌握计算机基础、编程基础语法,面向对象,集合、IO流、线程、并发、异常及网络编程,这些我们称之为JavaSE基础。当你掌握了这些内容之后,你就可以做出诸如:电脑上安装的迅雷下载软件、QQ聊天客户端、考勤管理系统等桌面端软件。 而这篇文章要写的,就是Java基础,有人看的话后面可能也会继续写计算机基础、数据库和框架这些。 在文末我也整理了一份书单Java架构师学习核心书单,各位可以按照自己的学习进度去酌情购买,如果是学生或者最近手头紧,也没有关系,我给大家收集了电子档,可以自行点击蓝字领取。 22本Java架构师核心书籍 从0到1Java学习路线和资料 1000+道2021年最新面试题 话不多说,坐稳扶好,发车喽! 一、Java基础语法
  • 2.8W字Java基础学习和书籍推荐,真正意义上的从0到1学Java,才不是培训机构那种大纲文
    前言 在网上一搜索Java学习会弹出无数文章,但全都是培训机构的大纲文,实在鸡肋,根本没写一个字是在帮助菜鸟怎么认识Java的,所以我琢磨着写一篇真正意义上的Java从0到1的文章,帮0基础的小白和初学的财年打开Java的大门 如果观察过招聘网站上的Java相关岗位需求就会发现,抛开其它的经验能力等等,单纯从技术,或者说知识上来讲,可以发现一些共通的地方。 Java基础 计算机基础 数据库,SQL/NoSQL 常用开源框架 分布式/微服务 中间件,缓存、消息中间件 学习任何一门编程语言,首先要学习的是基础语法,开启Java学习的第一步,当然就是深入掌握计算机基础、编程基础语法,面向对象,集合、IO流、线程、并发、异常及网络编程,这些我们称之为JavaSE基础。当你掌握了这些内容之后,你就可以做出诸如:电脑上安装的迅雷下载软件、QQ聊天客户端、考勤管理系统等桌面端软件。 而这篇文章要写的,就是Java基础,有人看的话后面可能也会继续写计算机基础、数据库和框架这些。 在文末我也整理了一份书单Java架构师学习核心书单,各位可以按照自己的学习进度去酌情购买,如果是学生或者最近手头紧,也没有关系,我给大家收集了电子档,可以自行点击蓝字领取。 22本Java架构师核心书籍 从0到1Java学习路线和资料 1000+道2021年最新面试题 话不多说,坐稳扶好,发车喽! 一、Java基础语法
  • 深入了解Serializable接口
    Serializalbe初步印象Serializalbe经常被用到Java实体对象时“implements Serializable”,一般都知道实现该接口是为了序列化。那么序列化目的是什么?查看Serializalbe接口源码是一个空接口,可以见是一个标志性接口。注解中说明没有实现此接口的类将不会对其状态进行任何序列化或反序列化,JVM通过这个标识来识别是否需要序列化。Serializable接口概述Serializable是java.io包中定义的、用于实现Java类的序列化操作而提供的一个语义级别的接口。Serializable序列化接口没有任何方法或者字段,只是用于标识可序列化的语义。实现了Serializable接口的类可以被ObjectOutputStream转换为字节流,同时也可以通过ObjectInputStream再将其解析为对象。例如,我们可以将序列化对象写入文件后,再次从文件中读取它并反序列化成对象,也就是说,可以使用表示对象及其数据的类型信息和字节在内存中重新创建对象。而这一点对于面向对象的编程语言来说是非常重要的,因为无论什么编程语言,其底层涉及IO操作的部分还是由操作系统其帮其完成的,而底层IO操作都是以字节流的方式进行的,所以写操作都涉及将编程语言数据类型转换为字节流,而读操作则又涉及将字节流转化为编程语言类型的特定数据类型
  • Java方法默认情况下应该是静态的吗?(Should Java methods be static by default?)
    问题 假设您正在类A中编写方法foo() 。foo永远不会访问A的任何状态。 您对foo的功能或其行为一无所知。 它可以做任何事情。 foo是否应该始终是静态的,而不考虑其他任何考虑因素? 为什么不? 在我分解任务并应用仅写一次原则时,我的班级似乎总是积累许多私有帮助器方法。 其中大多数都不依赖于对象的状态,但是在类自己的方法之外永远不会有用。 默认情况下它们应该是静态的吗? 最终使用大量内部静态方法是错误的吗? 回答1 要回答一般的标题问题,Java方法不应该是默认静态的。 Java是一种面向对象的语言。 但是,您谈论的内容有所不同。 您专门谈论辅助方法。 对于仅将值作为参数并返回值而不访问状态的辅助方法,它们应该是static 。 私有和静态。 让我强调一下: 不访问状态的辅助方法应该是静态的。 1.主要优点:代码更具表现力。 使这些方法静态化至少具有一个主要优点:您可以在代码中完全明确地使该方法不需要知道任何实例状态。 该代码不言自明。 对于将要阅读您的代码的其他人,甚至在将来的某个时刻,您来说,事情变得更加显而易见。 2.另一个优点:代码可以更简单地进行推理。 如果确定该方法不依赖于外部状态或全局状态,则它是一个纯函数,即数学意义上的函数:对于相同的输入,可以确定获得始终相同的输出。 3.优化优势 如果该方法是静态的并且是纯函数
  • Java自学笔记 同步印象笔记
    Java自学笔记 java简介: Java语言是简单的: Java语言的语法与C语言和C++语言很接近,使得大多数程序员很容易学习和使用。另一方面,Java丢弃了C++中很少使用的、很难理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。特别地,Java语言不使用指针,而是引用。并提供了自动的废料收集,使得程序员不必为内存管理而担忧。 Java语言是面向对象的: Java语言提供类、接口和继承等原语,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为implements)。Java语言全面支持动态绑定,而C++语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。 Java语言是分布式的: Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。 Java语言是健壮的: Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证。对指针的丢弃是Java的明智选择。Java的安全检查机制使得Java更具健壮性。 Java语言是安全的:
  • GUID到底是什么? 为什么在何处使用它?(What exactly is GUID? Why and where I should use it?)
    问题 GUID到底是什么? 为什么在何处使用它? 我已经在很多地方和Wikipedia中看到了对GUID的引用,但是告诉您在哪里使用它并不是很清楚。 如果有人可以回答这个问题,那就太好了。 谢谢 回答1 GUID从技术上讲代表全局唯一标识符。 实际上,它是一个128位结构,不太可能重复或产生冲突。 如果您进行数学运算,则值的范围为十亿分之一。 当您有多个独立的系统或客户端生成的ID需要唯一的ID时,请使用guid。 例如,如果我有5个客户端应用程序在ID上具有唯一约束的表中创建事务数据并将事务数据插入到表中,则请使用guids。 这避免了必须强制客户端首先从服务器请求发出的ID。 这对于对象工厂和系统非常有用,因为对象工厂和系统具有存储在不同表中的大量对象类型,在这些表中您不希望任何两个对象具有相同的ID。 这使得缓存和清除模式更容易实现。 回答2 GUID是“全局唯一标识符”。 您可以在需要标识符确保彼此不同的任何地方使用它。 通常,您只需要一个值是“本地唯一的”-例如,数据库表中的主键标识仅需要与该表中的其他行不同,但可以与其他表中的ID相同。 (这里不需要GUID) 当您要定义的ID必须与其他人(控件外部)要定义的ID不同时,通常会使用GUID。 ActiveX控件的接口标识符中的此类位置之一。 任何人都可以创建ActiveX,却不知道某人将通过什么其他控件来使用它们--
  • 普通的旧CLR对象与数据传输对象(Plain Old CLR Object vs Data Transfer Object)
    问题 POCO =普通旧CLR(或更好:Class)对象 DTO =数据传输对象 在这篇文章中有一个区别,但是坦率地说,我读过的大多数博客都以定义DTO的方式描述了POCO:DTO是用于在应用程序各层之间移动数据的简单数据容器。 POCO和DTO是同一件事吗? 回答1 POCO遵循OOP规则。 它应该(但不是必须)具有状态和行为。 POCO来自POJO,由Martin Fowler创造。 他使用术语POJO来使拒绝框架繁重的EJB实现更加性感。 POCO应该在.Net中的相同上下文中使用。 不要让框架来决定对象的设计。 DTO的唯一目的是转移状态,并且不应有任何行为。 有关使用此模式的示例,请参见Martin Fowler对DTO的解释。 区别在于: POCO描述了一种编程方法(老式的面向对象编程),其中DTO是一种用于使用对象“传输数据”的模式。 尽管您可以将POCO像DTO一样对待,但是这样做会冒创建贫血域模型的风险。 此外,由于DTO应该被设计为传输数据,而不是代表业务域的真实结构,因此结构上存在不匹配。 这样的结果是DTO往往比您的实际域平坦。 在任何合理复杂性的域中,几乎总是最好创建单独的域POCO并将其转换为DTO。 DDD(域驱动设计)定义了反腐败层(此处是另一个链接,但最好的办法是买书),这是一个很好的结构,可以使隔离清晰可见。 回答2
  • 在Java文件中定义包的目的是什么? [关闭](What is the purpose of defining a package in a Java file? [closed])
    问题 关门了。 这个问题是基于意见的。 它当前不接受答案。 想要改善这个问题吗? 更新问题,以便可以通过编辑此帖子以事实和引用的形式回答。 10个月前关闭。 改善这个问题 我是新手,只是了解到如果我定义说 package my.first.group.here; ... 那么该软件包中的Java文件将放置在my/first/group/here目录下。 将某些Java文件放入程序包的主要目的是什么? 另外,如果我选择采用这种方式,应该如何将它们分组? 谢谢 编辑:对于任何可能再次遇到相同问题的人,我刚刚从Sun的软件包中找到了本教程。 回答1 让我们从Wikipedia文章中描述的“ Java程序包”的定义开始: Java包是一种将Java类组织到类似于Modula模块的名称空间中的机制。 Java包可以存储在称为JAR文件的压缩文件中,从而使类可以成组下载,而不是一次下载得更快。 程序员通常还使用包来组织属于同一类别或提供类似功能的类。 因此,基于此, Java包只是用于组织类和防止类名冲突的一种机制。 您可以根据需要命名,但Sun已发布了一些在命名软件包时应使用的命名约定: 配套唯一程序包名称的前缀始终以全小写ASCII字母书写,并且应为顶级域名之一,当前为com,edu,gov,mil,net,org或英语的两个字母代码之一根据1981年的ISO标准3166确定国家。
  • 如何将Java序列化的对象写入和读取到文件中(How to write and read java serialized objects into a file)
    问题 我将向一个文件中写入多个对象,然后在我的代码的另一部分中检索它们。 我的代码没有错误,但是无法正常工作。 您能帮我发现我的代码有什么问题吗? 我从不同的网站阅读了不同的代码,但是没有一个对我有用! 这是将对象写入文件的代码:MyClassList是一个数组列表,其中包含我的类的对象(必须将其写入文件)。 for (int cnt = 0; cnt < MyClassList.size(); cnt++) { FileOutputStream fout = new FileOutputStream("G:\\address.ser", true); ObjectOutputStream oos = new ObjectOutputStream(fout); oos.writeObject(MyClassList.get(cnt)); } 我向输出流的构造函数添加了“ true”,因为我想将每个对象都添加到文件的末尾。 那是对的吗? 这是我的代码,用于从文件中读取对象: try { streamIn = new FileInputStream("G:\\address.ser"); ObjectInputStream objectinputstream = new ObjectInputStream(streamIn); MyClass readCase = (MyClass)