编程语言
首页 > 编程语言> > java学习-javabeans-property

java学习-javabeans-property

作者:互联网

property

java beans specification

7 properties

Properties are discrete, named attributes of a Java Bean that can affect its appearance or its behaviour.

对于java bean 的property 简单描述其就是独立的命名的属性可以影响 其表现和行为其包含以下类别

 

accessor methods

7.1 accessor methods

Properties are discrete, named attributes of a Java Bean that can affect its appearance or its behaviour.

 

For simple properties the accessor type signatures are: // 限定规范
  void setFoo(PropertyType value); // simple setter
  PropertyType getFoo(); // simple getter

accessor methods 实际就是 普通的 setter/getter 方法, 但其存在约定限制,要求 set操作必须是无返回值,有且仅有一个入参; 而getter 方法要求无入参有返回值; 

 

indexed properties

7.2 indexed properties

In addition to simple single-value properties, we also support indexed properties. An indexed
property supports a range of values. Whenever the property is read or written you just specify
an index to identify which value you want.
Property indexes must be Java “int”s.

 

For indexed properties the accessor type signatures are: // 规范
  void setter(int index, PropertyType value); // indexed setter
  PropertyType getter(int index); // indexed getter
  void setter(PropertyType values[]); // array setter
  PropertyType[] getter(); // array getter

indexed properties 指代的就是支持通过 index 执行相关 单个数据或多个相同数据类型 的 属性 setter/getter 操作; 且 要求限制 index 为 int 类型

 

exception on accessor methods 

7.3 Exceptions on accessor methods
  Both simple and indexed property accessor methods may throw checked exceptions.

  This allows property setter/getter methods to report exceptional conditions.

对于accessor methods 上定义的异常 也属于 property的一种

 

对于以下 bound/constrained 属性的定义 不再是简单的定义方式,而是需要借助java.beans.*下的相关工具

 

bound

A component can choose to provide a change notification service for some or all of its properties. Such properties are commonly known as bound properties, as they allow other components to bind special behaviour to property changes.
The PropertyChangeListener event listener interface is used to report updates to simple bound
properties. If a bean supports bound properties then it should support a normal pair of multicast
event listener registration methods for PropertyChangeListeners:
  public void addPropertyChangeListener(PropertyChangeListener x);
  public void removePropertyChangeListener(PropertyChangeListener x);

 

The event source should fire the event after updating its internal state.

对于bound 首先要求必须在对属性完成操作后,并执行相关的events操作; 并且 需要搭配 java.beans.PropertyChangeSupport

 

constrained

Sometimes when a property change occurs some other bean may wish to validate the change
and reject it if it is inappropriate.

 

The VetoableChangeListener event listener interface is used to report updates to constrained
properties. If a bean supports constrained properties then it should support a normal pair of
multicast event listener registration methods for VetoableChangeListeners:
  public void addVetoableChangeListener(VetoableChangeListener x);
  public void removeVetoableChangeListener(VetoableChangeListener x);

 对于 constrained 实际 就是在属性操作完成之前进行的相关校验操作,关于相关的listener 和 bound的区别在于 其使用的是 Vetoable*; 且需要搭配 java.beans.VetoableChangeSupport

 

/*
 * Copyright (c) 2020, guoxing, Co,. Ltd. All Rights Reserved
 */
package com.xingguo.java.beans.properties;

import java.beans.*;
import java.io.Serializable;

/**
 * Person
 *
 * @author guoxing
 * @date 2020/11/24 11:28 AM
 * @since
 */
public class Person implements Serializable {
    private String name;

    private int age;

    /**
     * javabeans - persistence
     * 首先要求实现 java.io.Serializable
     * 对于 不需要持久化的属性 要求 使用 "transient" 关键字保证其不会被持久化
     */
    // 设置当前Bean的属性变化支持工具
    // 强制属性更新
    private final transient PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
    // 勉强属性更新
    private final transient VetoableChangeSupport vetoableChangeSupport = new VetoableChangeSupport(this);

    public String getName() {
        return name;
    }


    /**
     * 当名称属性发生变化时,
     *
     * @param name
     */
    public void setName(String name) {
        String oldVal = this.name;
        String newVal = name;
        // 创建属性变更事件
        PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(this, "name", oldVal, newVal);
        // 勉强属性
        fireVetoableChange(propertyChangeEvent);
        this.name = name;
        // 强迫事件变更机制
        // 强迫事件变更发生在 属性成功变更之后
        // 属性变更后发布事件
        // 发布事件
        propertyChangeSupport.firePropertyChange(propertyChangeEvent);
    }

    public void fireVetoableChange(PropertyChangeEvent event) {
        try {
            // 校验要求name 不能为纯粹的数字
            String propertyName = event.getPropertyName();
            if ("name".equals(propertyName) && isNumeric(String.valueOf(event.getNewValue()))) {
                throw new PropertyVetoException("name属性要求不能为纯数字", event);
            }
            vetoableChangeSupport.fireVetoableChange(event);
        } catch (PropertyVetoException propertyVetoException) {
            throw new RuntimeException(propertyVetoException);
        }

    }

    public void addVetoableChangeListener(VetoableChangeListener listener) {

    }

    public void removeVetoableChangeListener(VetoableChangeListener listener) {

    }


    public void addPropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.removePropertyChangeListener(listener);
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public static boolean isNumeric(String str) {
        if (str == null) {
            return false;
        } else {
            int sz = str.length();

            for (int i = 0; i < sz; ++i) {
                if (!Character.isDigit(str.charAt(i))) {
                    return false;
                }
            }

            return true;
        }
    }
}
/*
 * Copyright (c) 2020, guoxing, Co,. Ltd. All Rights Reserved
 */
package com.xingguo.java.beans.properties;

import lombok.extern.slf4j.Slf4j;

/**
 * PersonPropertyDemo
 *
 * @author guoxing
 * @date 2020/11/24 11:38 AM
 * @since
 */
@Slf4j
public class PersonPropertyDemo {

    public static void main(String[] args) throws InterruptedException {
        // 对于当前线程捕获异常而言,只会捕获到异常,但并不能恢复当前线程; 因此对于同一个线程抛出异常后,当前线程就会结束,并不会继续向后执行
        Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
            log.error("当前线程捕获到的异常信息", e);
        });
        Person person = new Person();
        // 增加事件监听器
        person.addPropertyChangeListener(event -> {
            log.info("source:{}中的属性:{}发生变化,oldVal为{},newVal为{}",
                    event.getSource(),
                    event.getPropertyName(),
                    event.getOldValue(),
                    event.getNewValue());
        });

        // 修改name属性来触发属性变更事件
        // null -> "xingguo"
        person.setName("xinguo");
        // "xingguo" -> "guoxing"
        person.setName("guoxing");
        person.setName("123456"); // 按照 勉强属性原则,当前属性不为设置成功,并会抛出异常
        log.info("person.name:{}", person.getName());
    }
}

 

标签:properties,java,name,void,public,javabeans,property,event,属性
来源: https://www.cnblogs.com/xingguoblog/p/14030709.html