简体   繁体   English

Java bean的setter许可是否会返回?

[英]Does Java bean's setter permit return this?

can I define setter method to return this rather than void? 我可以定义setter方法来返回它而不是void吗?

Like: 喜欢:

ClassA setItem1() {
      return this;
}

ClassA setItem2() {
      return this;
}

then I can use new ClassA().setItem1().setItem2() 然后我可以使用新的ClassA()。setItem1()。setItem2()

There is a lot of misunderstanding about JavaBeans spec. 关于JavaBeans规范存在很多误解。

The main reason for it's existence is the unified Java "component" model. 它存在的主要原因是统一的Java“组件”模型。 It's a way to interact programatically with a Java Object using Reflection. 这是一种使用Reflection以编程方式与Java对象进行交互的方法。 The API itself is named JavaBeans Introspection . API本身名为JavaBeans Introspection Please, take a look at example usages and You will know a lot more than an average Java programmer does. 请看一下示例用法,您将比普通的Java程序员了解更多。

Introspection API can be used to manipulate GUI elements in an unified manner. Introspection API可用于以统一的方式操作GUI元素。 Your component exposes it's properties as a pairs of getters and setters so that they could be discovered and manipulated at run-time on a GUI builder's property sheet. 您的组件将其属性公开为一对getter和setter,以便可以在GUI构建器的属性表上在运行时发现和操作它们。

So, mixing fluent APIs and JavaBeans Spec in my opinion is a no-go. 因此,在我看来,混合流畅的API和JavaBeans Spec是不行的。 That's two completely unrelated concepts and can disrupt each other. 这是两个完全不相关的概念,可能会相互破坏。 JavaBeans Introspection might not work when method signature differs (return type). 当方法签名不同(返回类型)时,JavaBeans内省可能不起作用。

Take a look at this example (taken from linked tutorial): 看一下这个例子(摘自链接教程):

public class SimpleBean
{
private final String name = "SimpleBean";
private int size;

public String getName()
{
    return this.name;
}

public int getSize()
{
    return this.size;
}

public void setSize( int size )
{
    this.size = size;
}

public static void main( String[] args )
        throws IntrospectionException
{
    BeanInfo info = Introspector.getBeanInfo( SimpleBean.class );
    for ( PropertyDescriptor pd : info.getPropertyDescriptors() )
        System.out.println( pd.getName() );
}
}

This example creates a non-visual bean and displays following properties derived from the BeanInfo object: 此示例创建一个非可视bean并显示从BeanInfo对象派生的以下属性:

  • class
  • name 名称
  • size 尺寸

You might want to see what happens when You change void return type to anything else. 您可能希望看到将void返回类型更改为其他任何内容时会发生什么。 I have done so and the result is the same. 我这样做了,结果是一样的。 So, does that mean it's allowed? 那么,这是否意味着允许?

I'm afraid no. 我不敢。 The JavaBeans spec is quite strict about those method signatures. JavaBeans规范对这些方法签名非常严格。 It just happened that implementation is forgiving. 事实上,实施是宽容的。 Nonetheless, I'd disadvise mixing fluent interface with JavaBeans. 尽管如此,我还是不喜欢将流畅的界面与JavaBeans混合在一起。 You can't really rely that, if the discovery works now, it will also in future. 你不能真正依赖它,如果发现现在有效,它也将在未来使用。

But, from the other side - it looks like You don't use JavaBeans to full extent. 但是,从另一方面来看 - 看起来你并没有完全使用JavaBeans。 Only the getters/setters pair of method. 只有getters / setters对方法。 It's up to You how You implement and design Your APIs. 取决于您如何实施和设计您的API。

The JavaBeans Specification describes a JavaBean as: JavaBeans规范将JavaBean描述为:

A Java Bean is a reusable software component that can be manipulated visually in a builder tool Java Bean是可重用的软件组件,可以在构建器工具中以可视方式进行操作

They are required to provide introspection, customization, events and persistence among other properties (Section 2.1: What is a bean?) 他们需要在其他属性中提供内省,自定义,事件和持久性(第2.1节:什么是bean?)

It is common to call a "Java Bean" to a Plain Old Java Object with accessor methods following the JavaBeans Specification (Section 7.1 and 8.3). 通常使用JavaBeans规范(第7.1和8.3节)之后的访问器方法将“Java Bean”调用普通旧Java对象。 The truth is that such object could still be far from being compliant with all the requirements. 事实是,这样的对象仍然远远不能满足所有要求。

If the object your are defining in this class is actually a JavaBean then your method must return void according to JavaBean Specification, section 7.1 where accessor methods are described as follows: 如果您在此类中定义的对象实际上是JavaBean,那么您的方法必须根据JavaBean规范第7.1节返回void,其中访问器方法描述如下:

void setFoo(PropertyType value); // simple setter
PropertyType getFoo(); // simple getter

The section 8.3 named designed patterns for properties says: 第8.3节命名设计的属性模式说:

By default, we use design patterns to locate properties by looking for methods of the form: 默认情况下,我们使用设计模式通过查找表单的方法来定位属性:

public <PropertyType> get<PropertyName>();
public void set<PropertyName>(<PropertyType> a);

In addition, for boolean properties, we allow a getter method to match the pattern: 另外,对于布尔属性,我们允许getter方法匹配模式:

public boolean is<PropertyName>();

However, if your class is just a POJO then there is nothing wrong with using your method chaining strategy because you are allowed to deviate from the specification since you are not actually building a JavaBean. 但是,如果您的类只是一个POJO,那么使用您的方法链策略没有任何问题,因为您实际上不允许偏离规范,因为您实际上并没有构建JavaBean。 Not all the classes you define are supposed to be JavaBeans after all, right? 并非你定义的所有类都应该是JavaBeans,对吧?

Your might like to take a look at the Oracle JavaBeans Tutorial . 您可能希望了解Oracle JavaBeans教程

No reason you couldn't do that. 没理由你不能这样做。 Personally, if the setters are being used during object creation, I'd name them withItem1() and withItem2(). 就个人而言,如果在对象创建过程中使用了setter,我会将它们命名为Item1()和withItem2()。

ClassA obj = new ClassA().withItem1(item1).withItem2(item2);

Makes it a bit clearer (to me anyway) what the intent of the methods are. 使得它更清楚(对我来说)方法的意图是什么。

After checking the Oracle JavaBean pages I didn't find anything which explicitly tells you that the setters need to be void. 检查Oracle JavaBean页面后,我没有找到任何明确告诉您setter必须为void的内容。 Nevertheless all examples have void set-methods. 然而,所有示例都具有空集方法。

The PropertyDescriptor in the Java API support non-void setters, so I think it should be pretty safe to let your setters return this. Java API中的PropertyDescriptor支持非void setter,所以我认为让你的setter返回它应该是非常安全的。 To be on the safe side you should probably check out if the frameworks you intend to use that uses reflection. 为了安全起见,您应该查看您打算使用反射的框架。 For instance didn't Spring support non-void setters in xml config prior to version 3.1 . 例如, 在版本3.1之前的xml配置中,Spring支持非void setter

I would guess this is not in violation of the JavaBean specification, although I am not sure of it. 我猜这不违反JavaBean规范,虽然我不确定。

Check out the following example: 看看以下示例:

public class JavaBean {

    private String value;

    public String getValue() {
        return value;
    }

    public JavaBean setValue(String value) {
        this.value = value;
        return this;
    }

    public static void main(String[] args) throws Exception {
        JavaBean bean = new JavaBean();
        JavaBean.class.getMethod("setValue", String.class).invoke(bean, "test");
        System.out.println(bean.getValue());
    }
}

Many frameworks access JavaBeans using the reflection API. 许多框架使用反射API访问JavaBeans。 As you can see above, accessing a settter which returns 'this' is not influenced by the return type (the return type is not used to locate a method via reflection). 如上所示,访问返回'this'的清除程序不受返回类型的影响(返回类型不用于通过反射定位方法)。 It also makes sense, because you cannot have two methods in one scope that are identical except for their return type. 这也是有道理的,因为除了返回类型之外,在一个范围内不能有两个相同的方法。

Yes. 是。 This is a somewhat common technique called Method Chaining, and can be used to create a "fluent interface". 这是一种称为Method Chaining的常见技术,可用于创建“流畅的界面”。

See: http://en.wikipedia.org/wiki/Method_chaining , http://en.wikipedia.org/wiki/Fluent_interface 请参阅: http//en.wikipedia.org/wiki/Method_chaining,http//en.wikipedia.org/wiki/Fluent_interface

Absolutely nothing to stop you doing that but why. 绝对没有什么可以阻止你这样做,但为什么。 If you want to do this create a constructor that takes the args. 如果你想这样做,请创建一个带有args的构造函数。 Bare in mind some software that uses beans would not be expecting return values and may have some unexpected results 请记住,一些使用bean的软件不会期望返回值,并且可能会产生一些意想不到的结果

If you just want to simplify initialisation, (maybe to set up tests) you could use some groovy code. 如果您只是想简化初始化(可能要设置测试),您可以使用一些groovy代码。

Just to add that for people using Spring 3.1+ this is not an issue anymore 只是为使用Spring 3.1+的人添加它,这不再是一个问题

see http://static.springsource.org/spring/docs/3.1.0.M2/spring-framework-reference/html/new-in-3.1.html http://static.springsource.org/spring/docs/3.1.0.M2/spring-framework-reference/html/new-in-3.1.html

The Builder pattern is generally used for constructing immutable objects. Builder模式通常用于构造不可变对象。 Even though JavaBeans by nature aren't immutable, I have frequently used the builder pattern on my JavaBeans because it provides a fluent interface that I can use in my tests. 尽管JavaBeans本质上不是不可变的,但我经常在我的JavaBeans上使用构建器模式,因为它提供了一个流畅的接口,我可以在我的测试中使用它。 The two are easily compatible with each other without breaking the JavaBean specification. 这两者在不破坏JavaBean规范的情况下很容易相互兼容。 You can check out it out on Stack Overflow at Builder Pattern in Effective Java 您可以在Effective Java中的Builder Pattern上的Stack Overflow上查看它

You just need to make sure you include a default constructor as well as the private Builder constructor, and then put your standard getters and setters in the JavaBean object. 您只需要确保包含默认构造函数以及私有Builder构造函数,然后将标准getter和setter放在JavaBean对象中。

This is much cleaner than constructor chaining, and easier to read as well. 这比构造函数链更清晰,也更容易阅读。

There is nothing preventing you from providing setter methods which return the target object as a convention in your interface... 没有什么能阻止你提供setter方法,它们将目标对象作为接口中的约定返回...

However , you must also use the canonical signature for Java Bean Simple Property setter methods (eg void setProp(Type t) ) or the bean property will not be recognized as writeable by other software which expects that signature. 但是 ,您还必须使用Java Bean Simple Property setter方法的规范签名(例如void setProp(Type t) ),否则bean属性将不会被其他期望签名的软件识别为可写。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 具有静态setter函数的Java bean - java bean with static setter function Bean属性“ trustStore”不可写或具有无效的setter方法。 setter的参数类型是否与getter的返回类型匹配? - Bean property 'trustStore' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter? Bean 属性 'sakilaDao' 不可写或具有无效的 setter 方法。 setter 的参数类型是否与 getter 的返回类型匹配? - Bean property 'sakilaDao' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter? Bean 属性 &#39;xxx&#39; 不可读或具有无效的 getter 方法:getter 的返回类型是否与 setter 的参数类型匹配? - Bean property 'xxx' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter? Bean属性“ cmpcode”不可读或具有无效的getter方法:getter的返回类型是否与setter的参数类型匹配? - Bean property 'cmpcode' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter? Bean属性&#39;xxxx不可读或具有无效的getter方法:getter的返回类型是否与setter的参数类型匹配 - Bean property 'xxxx is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter 是否有不允许空值的基本 Java Set 实现? - Is there a basic Java Set implementation that does not permit nulls? Java中的setter约定(返回void或this) - Setter conventions in Java (return void or this) Spring MVC:Bean属性不可读或具有无效的getter方法getter的返回类型是否与setter的参数类型匹配 - Spring MVC: Bean property is not readable or has an invalid getter method Does the return type of the getter match the parameter type of the setter Bean属性不可读或具有无效的getter方法:getter的返回类型是否与setter的参数类型匹配? 春季批 - Bean property is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter? Spring Batch
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM