究竟啥是 JavaBean?
Posted
技术标签:
【中文标题】究竟啥是 JavaBean?【英文标题】:What is a JavaBean exactly?究竟什么是 JavaBean? 【发布时间】:2011-03-18 18:03:57 【问题描述】:我认为,“Bean”是具有属性和 getter/setter 的 Java 类。
据我了解,它相当于 C struct
。这是真的吗?
另外,JavaBean
和常规 class
之间是否存在真正的句法差异?
有什么特殊的定义或者Interface
吗?
基本上,为什么会有这样的术语?
还有Serializable
这个接口是什么意思?
【问题讨论】:
见places where Java Beans used?。这是一个遵循某些约定的类。 为了完整起见,这里是JavaBeans Specification的链接。 只是一个注释。如果你曾经听到人们抛出 POJO 这个词,他们通常实际上是指 Bean。当你看到 POJO 时,它们几乎总是有 setter 和 getter,是可序列化的……实际上 POJO 不需要 setter 和 getter、可序列化的接口或其他任何东西——它只是一个没有特定要求的普通 Java 对象。跨度> 绝对不是结构,但我很高兴你问了这个问题。 【参考方案1】:一个 bean is 一个 Java 类,其方法名称遵循 properties、methods 和 events 的 JavaBean 准则(也称为设计模式)。因此,任何不属于属性定义的 bean 类的公共方法都是 bean 方法。最低限度,一个 Java 类,即使有一个属性作为唯一成员(当然,需要公共 getter 和 setter),一个公共方法作为唯一成员,或者只有一个公共事件侦听器注册方法,也是一个 Java bean。此外,该属性可以是只读属性(具有 getter 方法但没有 setter)或只写属性(仅具有 setter 方法)。 Java bean 需要是一个公共类才能对任何 beanbox 工具或容器可见。容器必须能够实例化它;因此,它也应该有一个公共构造函数。 JavaBeans specification 不需要 bean 有一个公共的零参数构造函数,显式的或默认的,以便容器实例化它。如果您可以提供包含序列化实例的文件(扩展名为 .ser),那么 beanbox 工具可以使用该文件来实例化原型 bean。否则,bean 将需要一个公共的零参数构造函数,无论是显式的还是默认的。
一旦 bean 被实例化,JavaBean API (java.beans.*) 就可以对它进行内省并调用它的方法。如果没有实现接口 BeanInfo 或扩展 BeanInfo 实现的类 SimpleBeanInfo 类可用,则自省涉及使用反射(隐式自省)来研究目标 bean 支持的方法,然后应用简单的设计模式(指南)从这些方法支持哪些属性、事件和公共方法。如果实现接口 BeanInfo 的类(对于 bean Foo,它必须命名为 FooBeanInfo)可用,API 绕过隐式自省并使用该类的公共方法(getPropertyDescriptor()、getMethodDescriptors()、getEventSetDescriptors())来获取信息。如果扩展 SimpleBeanInfo 的类可用,取决于 SimpleBeanInfo 公共方法(getPropertyDescriptor()、getMethodDescriptors()、getEventSetDescriptors())中的哪一个被覆盖,它将使用这些被覆盖的方法来获取信息;对于未被覆盖的方法,它将默认为相应的隐式内省。一个 bean 无论如何都需要被实例化,即使它没有进行隐式自省。因此,公共零参数构造函数的要求。但是,当然,Serializable 或 Externalizable 接口并不是识别它所必需的。然而,Java Bean 规范说,“我们也希望它对于一个小 Bean 的常见情况是“微不足道的”,它只是想保存其内部状态并且不想考虑它。所以,所有bean 必须实现 Serializable 或 Externalizable 接口。
总的来说,JavaBeans 规范对于 bean 的构成并不严格。 “编写 JavaBeans 组件非常简单。您不需要特殊工具,也不必实现任何接口。编写 bean 只需遵循某些编码约定。您所要做的就是让您的类看起来像一个 bean——使用 bean 的工具将能够识别和使用你的 bean。”很简单,即使是下面的类也是一个 Java bean,
public class Trivial implements java.io.Serializable
如下所述,bean 是上述 Java SE 版本 (JavaBeans) 的 Java EE 版本。这些描述进一步说明了上述基本思想。
春豆
比如说,一个 bean 构造函数有一些参数。假设有些是简单类型。容器可能不知道要为它们分配什么值;即使是这样,生成的实例也可能无法重用。只有当用户可以像在 Spring bean 中那样通过注解或 xml 配置文件进行配置(指定值)时,它才有意义。并假设某些参数是类或接口类型。同样,容器可能不知道要为其分配什么值。只有当用户可以通过注解或 xml 配置文件进行配置(指定特定对象)时,它才有意义。然而,即使在 Spring(通过 xml 配置文件)中,将特定对象(带有字符串名称)分配给构造函数参数(构造函数参数的属性或元素)也不是类型安全的;它基本上类似于资源注入。引用其他 Spring bean(称为协作者;通过构造函数参数元素中的元素)基本上是依赖注入,因此是类型安全的。显然,一个依赖项(collaborator bean)可能有一个带有注入参数的构造函数;那些注入的依赖项可能有一个带参数的构造函数等等。在这种情况下,最终,您将需要一些 bean 类(例如,MyBean.class),容器可以通过简单地调用 new MyBean() 来实例化它们,然后它才能通过构造函数上的依赖注入构造其他协作 bean——因此,需要bean 具有公共的零参数构造函数。假设,如果容器不支持依赖注入和/或不允许像 Spring 中那样通过一些注释或 xml 配置文件将简单类型的值分配给构造函数,则 bean 构造函数不应该有参数。即使是 Spring bean 应用程序也需要一些 bean 来具有公共的零参数构造函数(例如,在 Spring 应用程序没有只有简单类型作为构造函数参数的 bean 的场景中)。
JSF 托管 Bean
JSF 托管 bean 在 Web 容器中运行。它们可以使用@ManagedBean 注解或应用程序配置资源文件 managed-bean.xml 进行配置。但是,它仅支持通过资源注入(非类型安全)进行注入;不适合在构造函数上注入。 JSF spec 要求托管 bean 必须具有公共零参数构造函数。此外,它还说,“从本规范的 2.3 版开始,强烈使用本节中指定的托管 bean 设施 灰心。解决相同问题的更好、更紧密集成的解决方案是使用 JSR-365 中指定的上下文和依赖注入 (CDI)。”换句话说,要使用的 CDI 托管 bean,它为类似的构造函数提供类型安全的依赖注入到Spring bean。CDI规范采用Managed Beans规范,适用于JEE平台的所有容器,而不仅仅是web层。因此,web容器需要实现CDI规范。
托管 Bean
这是Managed Bean specification 的摘录 “ Managed Beans 是具有最低要求的容器管理对象, 也称为首字母缩略词“POJO”(普通旧 Java 对象)……它们可以被视为 Java SE 平台上的 JavaBeans 组件模型的 Java EE 平台增强版本……。读者不会错过 Managed Beans 在 JavaServer Faces (JSF) 技术中发现的同名设施中的前身……本规范中定义的 Managed Beans 代表了 JSF 中的泛化;特别是,托管 Bean 可以在 Java EE 应用程序的任何地方使用,而不仅仅是在 Web 模块中。例如,在基本组件模型中,Managed Beans 必须提供无参数的构造函数,但建立在 Managed Beans 上的规范,例如 CDI (JSR-299),可以放宽该要求,并允许 Managed Beans 为构造函数提供更多复杂的签名,只要它们遵循一些明确定义的规则……托管 Bean 不能是:最终类、抽象类、非静态内部类。与常规 JavaBean 组件不同,托管 Bean 可能无法序列化。” 因此,托管 Bean(也称为 POJO 或 POJO bean)的规范允许在 CDI 中进行扩展。
CDI 豆
The CDI specification 将托管 bean 重新定义为: 在 Java EE 中运行时,如果满足要求,*** Java 类就是托管 bean:
• 它不是内部类。 • 它是一个非抽象类,或者被注释为@Decorator。 • 它没有实现javax.enterprise.inject.spi.Extension。 • 它没有注解@Vetoed 或在一个包中没有注解@Vetoed。 • 它有一个适当的构造函数,或者:类有一个没有参数的构造函数,或者类声明了一个带有@Inject 注释的构造函数。
所有满足这些条件的 Java 类都是托管 bean,因此没有特殊声明 需要定义托管 bean。 或者
如果它被任何定义为托管 bean 其他 Java EE 规范和 if
• 未使用 EJB 组件定义注释进行注释或声明为 EJB bean 类 在 ejb-jar.xml 中。
与 Spring bean 不同,它不支持具有简单类型的构造函数,如果它支持使用 xml 配置文件(如 Spring 或任何注释)进行配置,这可能是可能的。
EJB
EJB 在 EJB 容器中运行。它的specification 说:“会话 bean 组件是一个托管 Bean。”“该类必须有一个不带参数的公共构造函数,”它对会话 bean 和消息驱动 bean 都说。此外,它说,“会话 bean 类不需要实现 SessionBean 接口或 Serializable 接口。”与 JSF bean 一样,EJB3 依赖注入基本上是资源注入,JSF bean 不支持带参数的构造函数,即通过依赖注入。但是,如果 EJB 容器实现 CDI,“可选:该类可能有一个使用 Inject 注释注释的附加构造函数,“它对会话 bean 和消息驱动 bean 都说,因为,”打包到 CDI bean 存档中且未使用 javax.enterprise.inject.Vetoed 注释注释的 EJB 被认为是启用 CDI豆子。”
【讨论】:
文字墙。你能分解它们吗?也许还可以添加小节标题。 这是什么意思? 嗨@PeterMortensen 感谢您的指出。完成。 嗨@Farid 缺少分段,正如彼得莫滕森在评论中指出的那样,可能会抑制一些可读性/可理解性。否则,在发布我的答案并尝试写一个更好的答案之前,我已经在这里阅读了大多数答案。您现在可以阅读它,并且很高兴听到您的具体 cmets。 这个答案值得更多的支持。它不仅澄清了对 JavaBeans 的一些误解(例如,公共零参数构造函数只是约定,而不是规范允许的唯一选项),而且它将 JavaBeans 与许多其他常见的 bean 进行比较以提供更广泛的上下文。总结得很好。【参考方案2】:豆类 构成应用程序主干并由 Spring IoC 容器管理的对象称为 bean。 bean 是由 Spring IoC 容器实例化、组装和管理的对象。这些 bean 是使用您提供给容器的配置元数据创建的。
【讨论】:
【参考方案3】:上面重复了 6 到 7 次,JavaBeans 的构造函数要求是无参数的。
这是错误的,没有这样的要求,尤其是在 Java Spring 的上下文中。
在描述 JavaBeanns API (https://download.oracle.com/otndocs/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/) 的规范版本 (1.01) 中也没有提及该要求。更重要的是 - 本规范在以下情况下仅提到了 2 次“空构造函数”: “每个定制器都应该有一个空构造函数。” “每个 PropertyEditor 都应该有一个 null 构造函数。”
因此,规范的作者似乎不知道或不愿意使用术语“空构造函数”,对于 JavaBeans 本身仍然没有提及它。
【讨论】:
是的,所有的 cmets 都大错特错。 Java Beans 甚至可以通过@java.beans.ConstructorProperties
保持不变。原来的规范已经过时了,它甚至没有从那时起。唯一真正的“标准”是在java.beans.Introspector
中定义的。类真正做的唯一逻辑是检查是否存在具有 is/get/set 的方法。
在深入研究 JavaBeans 的兔子洞之后,我完全同意这个答案。 JavaBeans 是 Java 社区中被深深误解的概念。最初的 JavaBeans 规范没有提到空构造函数。只有那些字段可以通过适当命名的 getter/setter 访问。这种误解似乎也延伸到了大多数框架中。大多数框架都指定它们只使用 JavaBean 对象,而实际上它们意味着它们使用的对象必须遵守 JavaBeans 规范规定的 getter/setting 命名约定。【参考方案4】:
如果你熟悉 C/Golang,你从来没有听说过 C bean 或 Go bean,因为它们有 struct
关键字,开发人员可以轻松定义结构类型,而无需编写复杂的 OOP 关键字。
type User struct
Name string
Age int
var user User
user.Name = "name"
user.Age = 18
var bytes, err = json.Marshal(user)
缺少struct
类型是Java 的错误,开发人员发现了这种严重的不足。
然后,Java Bean 被发明为另一个无聊的规则,让class
伪装成struct
,你的编辑器或编译器不会因为你对类成员的不安全访问而哭泣或大喊大叫。
【讨论】:
你哭什么?类和结构有什么区别? JVM实现不一样吗?类似于v-table?【参考方案5】:Spring @Bean 注解表示一个方法产生一个由 Spring 容器管理的 bean。
更多参考:https://www.concretepage.com/spring-5/spring-bean-annotation
【讨论】:
【参考方案6】:Java Bean 是 JavaBeans 架构中的一个组件或基本构建块。 JavaBeans 架构是一种组件架构,它受益于基于组件的方法的可重用性和互操作性。
一个有效的组件架构应该允许程序从 软件构建块(在本例中为 Bean),可能由不同的供应商提供,也使架构师/开发人员可以选择组件(Bean)、了解其功能并将其合并到应用程序中。
由于类/对象是像 Java 这样的 OOP 语言的基本构建块,它们自然而然地成为 JavaBeans 架构中的 Bean 的竞争者。
将普通 Java 类转换为 Java bean 的过程实际上只不过是使其成为可重用和可互操作的组件。这将转化为具有以下能力的 Java 类:
-
控制向另一个应用程序公开的类的属性、事件和方法。 (您可以拥有一个仅报告外部应用程序需要的属性、事件和方法的 BeanInfo 类。)
持久性(可序列化或可外部化 - 这也意味着具有无参数构造函数,对字段使用瞬态)
能够注册事件并生成事件(例如,利用绑定和约束属性)
定制器(通过 GUI 或提供文档来定制 Bean)
为了将 Java 类称为 Java bean,它们不需要具备上述所有能力。相反,它意味着实现上述与上下文相关的子集(例如,某个框架中的 bean 可能不需要定制器,其他一些 bean 可能不需要绑定和约束属性等)
几乎所有领先的 Java 框架和库都隐含地遵循 JavaBeans 架构,以便获得上述好处。
【讨论】:
【参考方案7】:POJO(普通旧 Java 对象):POJO 是普通的 Java 对象,除了 Java 语言强制的限制之外没有其他限制。
序列化:用于保存对象的状态并通过网络发送。它将对象的状态转换为字节流。我们可以通过称为 deserialization 的过程从字节流中重新创建 Java 对象。
让你的类实现 java.io.Serializable 接口。并使用ObjectOutputStream类的writeObject()方法实现序列化。
JavaBean 类:它是一个特殊的 POJO,有一些限制(或约定)。
-
实现序列化
有公共的无参数构造函数
具有公共 getter 和 setter 方法的所有私有属性。
许多框架(如 Spring)使用 JavaBean 对象。
【讨论】:
【参考方案8】:只是关于 bean 概念的一点背景/更新。许多其他答案实际上有它们的什么,但没有那么多为什么。
它们是早期在 Java 中作为构建 GUI 的一部分而发明的。他们遵循易于工具拆分的模式,让他们创建一个属性面板,以便您可以编辑 Bean 的属性。一般来说,Bean 属性代表屏幕上的一个控件(想想 x,y,width,height,text,..)
您也可以将其视为强类型数据结构。
随着时间的推移,这些对于使用相同类型访问的许多工具变得有用(例如,Hibernate 将数据结构持久保存到数据库)
随着工具的发展,它们更倾向于注解,而不是分离 setter/getter 名称。现在大多数系统都不需要 bean,它们可以使用任何带有注释属性的普通旧 Java 对象来告诉它们如何操作它们。
现在我将 bean 视为带注释的属性球——它们实际上只对它们携带的注释有用。
Beans 本身并不是一个健康的模式。它们本质上破坏了封装,因为它们将所有属性暴露给外部操作,并且在使用它们时,有一种趋势(绝不是要求)创建代码以在外部操作 bean,而不是在 bean 内部创建代码(违反“don '不要向一个对象询问它的值,而是要求一个对象为你做某事”)。使用带有最少 getter 且没有 setter 的带注释的 POJO 更能恢复封装并具有不可变性的可能性。
顺便说一句,随着所有这些事情的发生,有人将这个概念扩展到了一种叫做 Enterprise Java Beans 的东西。这些是……不同的。而且它们足够复杂,以至于许多人觉得他们不了解整个 Bean 概念并停止使用该术语。我认为这就是为什么您通常会听到将 bean 称为 POJO 的原因(因为每个 Java 对象都是 POJO,这在技术上是可以的,但是当您听到有人说 POJO 时,他们通常会想到遵循 bean 模式的东西)
【讨论】:
正确 - 违反“不要向对象询问它的值,而是要求一个对象为你做某事”)【参考方案9】:Java Bean 是满足以下三个条件的任何 Java 类:
-
它应该实现可序列化接口(一个标记接口)。
构造函数应该是公共的并且没有参数(其他人称之为“无参数构造函数”)。
它应该有 getter 和 setter。
请注意,serialVersionUID 字段对于维护对象状态很重要。
以下代码符合 bean 的条件:
public class DataDog implements java.io.Serializable
private static final long serialVersionUID = -3774654564564563L;
private int id;
private String nameOfDog;
// The constructor should NOT have arguments
public DataDog ()
/** 4. getter/setter */
// Getter(s)
public int getId()
return id;
public String getNameOfDog()
return nameOfDog;
// Setter(s)
public void setId(int id)
this.id = id;
public void setNameOfDog(String nameOfDog)
this.nameOfDog = nameOfDog;
【讨论】:
【参考方案10】:Java Bean 是应遵循以下约定的 Java 类(概念):
-
它应该有一个无参数的构造函数。
它应该是可序列化的。
它应该提供设置和获取属性值的方法,称为 getter 和 setter 方法。
它是一个可重用的软件组件。它可以将许多对象封装到一个对象中,以便可以从多个位置访问同一个对象,并且是朝着易于维护代码迈出的一步。
【讨论】:
在谈到 java bean 时,我喜欢“可重用软件组件”这个短语——因为 java bean 通常什么都不做。 @Rodney P. Barbati:是的,但在我看来它是抄袭的(尽管搜索不成功)。至少在 2016 年、2017 年和 2018 年,OP 遗漏了大多数文章(参见其他帖子,例如 this example from 2018),但在这篇文章中,大部分文章都包含在内。或者换句话说,这篇文章中的写作风格不符合 OP 其他帖子的写作风格。 2016.【参考方案11】:JavaBeans 是一个标准,它的基本语法要求已在其他答案中明确说明。
但是,IMO,它不仅仅是一个简单的语法标准。 JavaBeans的真正含义或预期用途是,与围绕标准的各种工具支持一起,促进代码重用和基于组件的软件工程,即使开发人员能够通过组装现有组件(类)来构建应用程序,而无需编写任何代码(或者只需要写一点胶水代码)。不幸的是,这项技术被业界低估和利用不足,这可以从这个帖子的答案中看出。
如果您阅读 Oracle 的tutorial on JavaBeans,您可以对此有更好的理解。
【讨论】:
有用的帖子和链接。当我想到 bean 时,我确实会想到“Visual Builder”类型的东西,如 Oracle 文章中所示。我想知道是否还有许多其他框架大量使用它们...... 而不是像to facilitate code reuse and component-based software engineering, i.e. enable developers to build applications by assembling existing components (classes) and without having to write any code (or only have to write a little glue code).
这样的垃圾词,你可以举一个例子来说明“促进代码重用”的意思【参考方案12】:
它们是可序列化的,具有零参数构造函数,并允许使用 getter 和 setter 方法访问属性。 “Bean”这个名字是为了包含这个标准,它旨在为 Java 创建可重用的软件组件。 根据Wikipedia.
构成应用程序主干并由 Spring IoC 容器管理的对象称为 bean。 bean 是由 Spring IoC 容器实例化、组装和管理的对象。否则,bean 只是应用程序中的众多对象之一。 根据Spring IoC.
【讨论】:
【参考方案13】:根据***:
该类必须有一个公共的默认构造函数(不带参数)。这允许在编辑和激活框架内轻松实例化。
根据标准命名约定,必须使用 get、set、is(可用于布尔属性而不是 get)和其他方法(所谓的访问器方法和 mutator 方法)来访问类属性。这允许在框架内轻松自动检查和更新 bean 状态,其中许多框架包括用于各种类型属性的自定义编辑器。 Setter 可以有一个或多个参数。
该类应该是可序列化的。 (这允许应用程序和框架以独立于 VM 和平台的方式可靠地保存、存储和恢复 bean 的状态。)
更多信息请关注link。
【讨论】:
之前的答案不是已经涵盖了吗? 我很确定 OP(和我们大多数人)在这里是为了解释而不是复制粘贴文本【参考方案14】:Java Beans 用于更少代码和更多工作的方法......
Java Bean 在整个 Java EE 中被用作运行时发现和访问的通用契约。例如,JavaServer Pages (JSP) 使用 Java Bean 作为页面之间或 servlet 和 JSP 之间的数据传输对象。 Java EE 的 JavaBeans 激活框架使用 Java Beans 将 MIME 数据类型的支持集成到 Java EE 中。 Java EE 管理 API 使用 JavaBeans 作为在 Java EE 环境中管理资源的基础。
关于序列化:
在对象序列化中,对象可以表示为一个字节序列,其中包括对象的数据以及有关对象类型和对象中存储的数据类型的信息。
序列化的对象写入文件后,可以从文件中读取并进行反序列化,即表示对象及其数据的类型信息和字节可用于在内存中重新创建对象。
【讨论】:
【参考方案15】:要了解 JavaBean,您需要注意以下几点:
JavaBean 是概念性的东西,不能代表一类具体的东西
JavaBean 是一种开发工具,可以在可重用的软件组件中进行可视化操作
JavaBean 基于 Sun JavaBeans 规范,是可重用的组件。它最大的特点就是可重用性。
【讨论】:
【参考方案16】:在跨多个服务器部署项目时,您会发现序列化很有用,因为 bean 将被持久化并在它们之间传输。
【讨论】:
能否提供更多关于跨多台服务器部署项目的信息?谢谢 说一个有几个服务器的集群,对于 Websphere 这个链接***.com/questions/3193345/… 可能会有所帮助。【参考方案17】:JavaBeans 是遵循极其简单的编码约定的 Java 类。 你所要做的就是
-
实现
java.io.Serializable
接口——保存一个状态
对象
使用公共空参数构造函数 - 实例化对象
提供公共 getter/setter 方法 - 获取和设置私有变量(属性)的值。
【讨论】:
这样简单的解释正是我想要的。谢谢!【参考方案18】:关于您问题的第二部分,序列化 是一种持久性机制,用于将对象存储为有符号字节序列。不太正式地说,它存储对象的状态,以便您以后可以通过反序列化检索它。
【讨论】:
【参考方案19】:有一个术语可以让它听起来很特别。现实远没有这么神秘。
基本上是一个“豆子”:
是一个可序列化的对象(也就是说,它实现了java.io.Serializable
,并且正确地实现了),即
具有“属性”,其 getter 和 setter 只是具有特定名称的方法(例如,getFoo()
是“Foo”属性的 getter),并且
有一个公共的零参数构造函数(因此可以随意创建并通过设置其属性进行配置)。
至于Serializable
:那不过是一个“标记接口”(一个不声明任何函数的接口),它告诉Java实现类同意(并暗示它能够)“序列化” -- 将实例转换为字节流的过程。这些字节可以存储在文件中,通过网络连接发送等,并且有足够的信息允许 JVM(至少,知道对象类型的)稍后重建对象 - 可能在不同的实例中应用程序,甚至在另一台机器上!
当然,为了做到这一点,类必须遵守某些限制。其中最主要的是,所有实例字段必须是原始类型(int、bool 等)、某些也可序列化的类的实例,或者标记为transient
,这样 Java 就不会尝试包含它们。 (这当然意味着transient
字段将无法在流中运行。具有transient
字段的类应准备好在必要时重新初始化它们。)
一个不能遵守这些限制的类不应该实现Serializable
(而且,IIRC,Java 编译器甚至不会让它这样做。)
【讨论】:
这可能是一个愚蠢的问题,但是,除了原始类型或类的实例之外,实例字段还能是什么? @kingfrito_5005:这将是一个或另一个。但是,如果它是一个类的实例,那么该类是否可序列化就很重要。为了使一个类可序列化,它的非transient
部分必须是某种可序列化的类型。
可能忘了说构造函数应该没有参数。有一个公共的默认构造函数(因此可以随意创建并通过设置其属性进行配置)。
@AmosKosgei:没有忘记;这只是多余的。根据定义,默认构造函数可以不带参数调用。
@Amos:不过,在我看来,“默认构造函数”在 Java 中的含义与在 C++ 中的含义略有不同。 :P 将“默认”替换为“0-arg”。【参考方案20】:
JavaBean 只是一个standard
-
所有属性都是私有的(使用getters/setters)
公众no-argument constructor
实现
Serializable
。
就是这样。这只是一个约定。不过很多库都依赖它。
关于Serializable
,来自API documentation:
类的可序列化性由实现 java.io.Serializable 接口。没有实现这个的类 接口不会对它们的任何状态进行序列化或反序列化。 可序列化类的所有子类型本身都是可序列化的。这 序列化接口没有方法或字段,仅用于 识别可序列化的语义。
换句话说,可序列化对象可以写入流,因此可以写入文件、对象数据库等等。
此外,JavaBean 和另一个类之间在语法上没有区别——如果一个类遵循标准,那么它就是一个 JavaBean。
它有一个术语,因为该标准允许库以编程方式处理您以预定义方式定义的类实例。例如,如果一个库想要流式传输您传递给它的任何对象,它知道它可以,因为您的对象是可序列化的(假设库要求您的对象是正确的 JavaBeans)。
【讨论】:
好吧,在我看来,几乎所有围绕 bean 的文档都无法像您所拥有的那样简洁地描述该术语。 +1 是否要求 bean 的成员也是 bean?似乎是一个合理的要求.. @worldsayshi - 不,这不是必需的。例如,一个 bean 可以包含一个字符串;并且 String 不是 bean。 (String 是不可变的,因此您不能通过调用空构造函数和 setter 来创建它。) Serializable 对象应该具有 Serializable 成员似乎是合理的,除非它以某种方式从外部序列化它们。所以不,Java bean 成员不需要具有 Java bean 的任何方面。虽然如果它们也是 bean 会更简单。 “所有属性私有”不正确。从 getter 和 setter 推断属性(如果有方法 X getFoo() -> bean 有一个名为“foo”的可读属性;如果有方法 setFoo(X foo) -> bean 有一个名为“富”)。属性可以由通常是私有的成员字段(但不一定是)支持。 我希望成为一个Java bean“一个类必须是Public”。它真的需要实现可序列化接口吗??【参考方案21】:在实践中,Bean 只是易于使用的对象。序列化它们意味着能够轻松地持久化它们(以易于恢复的形式存储)。
Beans 在现实世界中的典型用途:
简单的可重用对象 POJO(普通旧 Java 对象) 视觉对象 Spring 使用 Beans 来处理对象(例如,需要在 session 中序列化的 User 对象) EJB(企业 Java Beans),更复杂的对象,如 JSF Beans(JSF 是旧的相当过时的技术)或 JSP Beans所以事实上,Beans 只是一个约定/标准,它期望 Java 对象的某些行为(序列化)并给出一些改变它的方法(属性的设置器)方式。
如何使用它们,只是你的发明,但我在上面列出了最常见的情况。
【讨论】:
【参考方案22】:举例说明。
1.导入 java.io.Serializable
至于序列化,见documentation。
2。私有字段
字段应该是私有的,以防止外部类轻松修改这些字段。 不是直接访问这些字段,而是使用通常的 getter/setter 方法。
3.构造函数
没有任何参数的公共构造函数。
4.获取器/设置器
用于访问和修改私有字段的 Getter 和 setter 方法。
/** 1. import java.io.Serializable */
public class User implements java.io.Serializable
/** 2. private fields */
private int id;
private String name;
/** 3. Constructor */
public User()
public User(int id, String name)
this.id = id;
this.name = name;
/** 4. getter/setter */
// getter
public int getId()
return id;
public String getName()
return name;
// setter
public void setId(int id)
this.id = id;
public void setName(String name)
this.name = name;
【讨论】:
我猜是setId(int id)
body 你想说的是this.id = id;
而不是this.id = is;
【参考方案23】:
JavaBean 的属性
JavaBean 是满足某些编程约定的 Java 对象:
JavaBean 类必须实现 Serializable
或
Externalizable
JavaBean 类必须有一个无参数构造函数
所有 JavaBean 属性都必须有公共的 setter 和 getter 方法
所有 JavaBean 实例变量都应该是私有的
JavaBean 示例
@Entity
public class Employee implements Serializable
@Id
private int id;
private String name;
private int salary;
public Employee()
public Employee(String name, int salary)
this.name = name;
this.salary = salary;
public int getId()
return id;
public void setId( int id )
this.id = id;
public String getName()
return name;
public void setName( String name )
this.name = name;
public int getSalary()
return salary;
public void setSalary( int salary )
this.salary = salary;
【讨论】:
注解是必需的还是 Java Bean 的一部分? @giannischristofakis 不,注释不是必需的。注释是 Spring 框架的一部分,它广泛使用 Java Bean。 为什么需要一个无参构造函数? @Renato 这很简单。想想 spring 必须使用 arg-constructor 自动实例化你的 bean ......它将作为参数传递什么? ;)以上是关于究竟啥是 JavaBean?的主要内容,如果未能解决你的问题,请参考以下文章