什么是包装类?
Posted
技术标签:
【中文标题】什么是包装类?【英文标题】:What is a wrapper class? 【发布时间】:2010-10-27 17:05:24 【问题描述】:这些类有什么用?
【问题讨论】:
【参考方案1】:一般来说,包装类是“包装”或“封装”另一个类或组件的功能的任何类。通过提供底层类或组件的实现的抽象级别,这些很有用;例如,包装 COM 组件的包装器类可以管理调用 COM 组件的过程,而不用打扰调用代码。它们还可以通过减少涉及的接口点数量来简化底层对象的使用;通常,这可以更安全地使用底层组件。
【讨论】:
当包装器必须尊重特定接口并且必须支持多态行为时,使用包装器类(作为适配器)。另一方面,当人们想要一个更简单或更简单的界面来使用时,就会使用外观。 在这篇文章中,建议包装器可用于为后期绑定类创建严格定义的代理:Can I use late binding...。除了上面描述的 Paul Sonier 之外,这是对包装器的有效附加用途吗? @NirajanSingh Wrapper 重用了两个已经存在的接口,并使一个与另一个协同工作。另一方面,Facade 创建了一个新界面。【参考方案2】:顾名思义:一个将另一个类或 API 的功能“包装”在更简单或只是不同的 API 中的类。
见:Adapter pattern, Facade pattern
【讨论】:
是的!通常是 Facade 模式的同义词。在许多代码文档中,我看到了明显的 Facade 方法,被描述为“Wrapper to XX::yy method”或像“Wrapper to XX::yy method with exception handling”这样的小癖好。【参考方案3】:包装类提供了一种将原始类型用作对象的方法。对于每个原语,我们都有一个包装类,例如,
int Integer
byte Byte
Integer 和 Byte 是原始 int 和 byte 的包装类。当您需要将原语用作对象时存在时间/限制,因此包装类提供了一种称为装箱/拆箱的机制。
概念可以通过下面的例子很好理解为
double d = 135.0 d;
Double doubleWrapper = new Double(d);
int integerValue = doubleWrapper.intValue();
byte byteValue = doubleWrapper.byteValue();
string stringValue = doubleWrapper.stringValue();
这样,我们也可以使用包装类类型转换为其他原始类型。当您需要将原始类型转换为对象并使用它们来获取其他原始类型时,使用这种类型的转换。尽管对于这种方法,您需要编写大量代码。然而,同样可以通过简单的铸造技术来实现,因为代码 sn-p 可以实现如下
double d = 135.0;
int integerValue = (int) d ;
虽然双精度值被显式转换为整数值,也称为向下转换。
【讨论】:
您的回答暗示包装类仅适用于原始对象。 您的答案仅在严格的 Java 术语中有效,而原始问题与语言无关。【参考方案4】:包装类不一定需要包装另一个类。它可能是一个 API 类包装功能,例如一个dll文件。
例如,创建一个 dll 包装类可能非常有用,它负责所有 dll 初始化和清理,并创建包装从例如创建的函数指针的类方法。 GetProcAddress()
.
干杯!
【讨论】:
【参考方案5】:包装类是一个“包装”其他东西的类,就像它的名字一样。
更正式的定义是实现Adapter Pattern 的类。这允许您将一组 API 修改为更可用、更易读的形式。例如,在 C# 中,如果您想使用原生 Windows API,将其包装到符合 .NET 设计准则的类中会有所帮助。
【讨论】:
根据我对适配器模式的理解,它与包装器不同:如果 X 包装了 Y,那么 X 应该封装 Y 的 state,而不是 它的身份。给定两个 X 实例,它们都包装了 Y,应该没有任何方法可以证明 X 的两个实例都包装了 Y 的 same 实例。相比之下,适配器对象通常会封装身份但不封装状态;对正在适配的对象的更改不会被视为对适配器本身的更改。【参考方案6】:有几种设计模式可以称为包装类。
查看我对“How do the Proxy, Decorator, Adaptor, and Bridge Patterns differ?”的回答
【讨论】:
【参考方案7】:值得注意的是,在某些环境中,包装类所做的大部分工作都被方面所取代。
编辑:
一般来说,包装器会扩展被包装物所做的事情,而不关心被包装物的实现,否则包装与扩展被包装类相比毫无意义。一个典型的例子是围绕其他一些服务接口添加计时信息或日志功能,而不是将其添加到该接口的每个实现中。
这最终成为了 Aspect 编程的典型示例。不是逐个函数地遍历接口函数并添加样板日志,而是在方面编程中定义一个切入点,它是一种方法的正则表达式,然后声明要在所有匹配的方法之前、之后或周围执行的方法切入点。可以公平地说,切面编程是对装饰器模式的一种使用,包装类也可以用于这种模式,但这两种技术都有其他用途。
【讨论】:
【参考方案8】:包装类是包装另一个类并提供客户端和被包装的原始类之间的抽象的类。
【讨论】:
【参考方案9】:包装类通常是一个将对象作为私有属性的类。包装器实现了该私有对象的 API,因此它可以作为私有对象的参数传递。
假设您有一个集合,并且您希望在将对象添加到其中时使用某种转换 - 您编写一个包含所有集合方法的包装类。当 add() 被调用时,包装器翻译参数而不是仅仅将它们传递到私有集合中。
包装器可以在任何可以使用集合的地方使用,并且私有对象仍然可以让其他对象引用它并读取它。
【讨论】:
同意,我个人对包装器的看法是,它们看起来和感觉都像原始类型,并且可以实现相同的接口,明确地保持被包装实例的状态。它们的存在是为了“拦截”对成员的调用。【参考方案10】:包装类是用于包装另一个类以在客户端和被包装的原始类之间添加一层间接和抽象的类。
【讨论】:
【参考方案11】:Wrapper 类是原始数据类型的包装器。它表示相应类实例中的原始数据类型,例如布尔数据类型可以表示为布尔类实例。 Java 中的所有原始包装类都是不可变的,即一旦为包装类实例分配了值,就无法进一步更改。
【讨论】:
【参考方案12】:Java 编程为每个原始数据类型提供包装类,将原始数据类型转换为包装类对应的对象。
【讨论】:
【参考方案13】:使包装类健康并不是一件容易的事。 理解一个包装类是如何被其他人设计的也不是一件容易的事。 因为它是想法,而不是代码。 只有理解了idea,才能理解wrapper。
【讨论】:
【参考方案14】:包装类的存在是为了满足程序员的基本需求——即在只允许对象的地方使用原始值。正如他们的名字所暗示的,包装类包装一个原始值并将该值保存在一个对象中。因此,所有不允许使用原语的地方——例如泛型、hashmap-keys、Arraylists 等——程序员现在可以选择将这些原语值作为其对应的包装类型提供。
此外,这些包装器类型具有许多实用方法,用于从原始类型转换为相应的包装器类型并返回,以及从字符串转换为包装器类型并返回。
我在我的博客中写了一篇关于包装类的详细文章,它深入解释了包装类型的概念 - http://www.javabrahman.com/corejava/java-wrapper-classes-tutorial-with-examples/ (披露 - 此博客归我所有)
【讨论】:
【参考方案15】:我目前为我的项目使用了一个包装类,我得到的主要好处(只是扩大主题解释的一个好处):
异常处理:我的主类,另一个类包装,如果发生任何异常,就会抛出异常的方法,所以我创建了一个包装类来处理异常并立即记录它们。因此,在我的主要范围内,没有异常处理。我只是调用一个方法并做一些事情。
易于使用:我可以轻松地启动对象。通常启动阶段由很多步骤构成。
代码可读性:当其他程序员打开我的代码时,代码看起来非常清晰且易于操作。
隐藏细节:如果你正在生成一个其他程序员将要使用的类,那么你可以将诸如“错误处理、异常处理、日志消息等……”之类的细节包装起来,这样程序员就不会被必须处理混乱,只需使用方法即可。
【讨论】:
【参考方案16】:包装类是一个仅用于保存某些东西并向其添加一些功能的类。 在 Java 中,因为原语(如整数、浮点数、字符......)不是对象,所以如果你想像对待它们一样对待它们,那么你必须使用包装类。 假设你想创建一个整数向量,问题是向量只包含对象而不是基元。所以你要做的就是把所有的整数放在一个整数包装器中并使用它。示例:
int number = 5;
Integer numberWrapped = new Integer(number);
//now you have the int in an object.
//and this is how to access the int value that is being wrapped.
int again = numberWrapped.intValue();
【讨论】:
这被称为装箱原语而不是包装。【参考方案17】:包装器是用于在不同平台之间的两个不同应用程序之间进行通信的类
【讨论】:
我认为你可以用它做的不仅仅是一个案例 确实,这只是一个小用例。 我想这就是网络服务的定义以上是关于什么是包装类?的主要内容,如果未能解决你的问题,请参考以下文章