Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java PropertyChangeSupport和equals方法_Java_Equals_Javabeans_Propertychangesupport - Fatal编程技术网

Java PropertyChangeSupport和equals方法

Java PropertyChangeSupport和equals方法,java,equals,javabeans,propertychangesupport,Java,Equals,Javabeans,Propertychangesupport,我会尽可能清楚地解释我的问题:)。我正在使用PropertyChangeSupport通知注册视图属性的更改。其中一个属性是一个对象,它的属性每查看几秒钟就会更改一次。我不想每次更新这个特定对象时都为它创建新实例(让propertychangelistener注意到更改),所以我编写了自己的equals方法,在其中我将比较值分配给自身 @Override public boolean equals(Object item) { // do not compare // if (

我会尽可能清楚地解释我的问题:)。我正在使用PropertyChangeSupport通知注册视图属性的更改。其中一个属性是一个对象,它的属性每查看几秒钟就会更改一次。我不想每次更新这个特定对象时都为它创建新实例(让propertychangelistener注意到更改),所以我编写了自己的equals方法,在其中我将比较值分配给自身

@Override
public boolean equals(Object item) {
    // do not compare 
    // if (this == item) { return true; }

    if (!(item instanceof TransferQueueItem) || 
        item == null) {

        return false;
    }

    TransferQueueItem newItem = (TransferQueueItem) item;
    boolean value = 
            // ommited... properties comparation
    return value;
}
不幸的是,这没有我想要的效果。如果我创建对象的副本并对其激发属性更改方法,那么它可以正常工作

我错过了什么

--编辑


我意识到,因为我使用的是同一个实例,而不是它的副本,所以属性指向同一个地方,因此比较总是正确的。除创建副本外,是否有解决方法。或者每秒创建一个对象的副本有多糟糕,例如,

您必须始终返回
true
以告知
PropertyChangeSupport
您的对象没有更改。但这意味着该类的所有对象的
equals()

更好的方法是为此类对象提供一个特殊的方法
firePropertyChange()
,该方法执行特殊处理。这样,您甚至可以避免创建
PropertyChangeEvent
的实例。下面是一个处理
BigDecimal
的示例(其中
equals()
根本不起作用):

[编辑]您所做的完全是另一回事:您有一个父项和一个子项,您希望父项的侦听器在子项更改时接收事件


正确的方法是将
PropertyChangeSupport
添加到子级。将子项添加到父项时,父项必须在子项中安装必要的侦听器。触发事件时,它必须触发第二个事件,通知父级的侦听器子级的更改(父级必须转发事件)。

这是链式propertychangelisteners的情况:

TransferQueueItem应启动自己的PropertychangeEvents,插入其中的TransferQueue必须侦听这些事件

作为响应,TransferQueue必须通知其侦听器所拥有的项已更改

每次我遇到这样的问题,对象必须重新启动事件时,我(我的工作团队)都会使用这种约定:

1对象只能启动源为自身的事件

2如果需要委托事件,它将启动如下事件:new Property ChangeEvent(此“委托事件”,null,receivedEvent)。这样听众就可以跟踪事件链


另外,我在一个Util类中有一个静态方法,它遵循事件链并返回第一个事件,其中一个属性不是“DELEGATED_event”

实际上我想要的是相反的。始终返回硬编码值并不是equals应该做的事情。在这种情况下,您的问题就不清楚了。是否要避免为TransferQueueItem的任何更改触发事件?TransferQueueItem更改时是否始终需要事件?当TransferQueueItem的属性更改时,是否始终需要事件?请注意,设置新的TransferQueueItem还是更改TransferQueueItem的属性是不同的。我不会在每次TransferQueueItem更改时都创建事件,但TransferQueueItem只是TransferQueue的一个属性,因此,它不是触发事件的对象。侦听器将自己添加到TransferQueue对象,而TransferQueue对象也是触发propertychange事件的对象。这并不重要,因为对同一实例的任何更改都会向该实例的所有侦听器触发事件。你遗漏了一些重要信息。谢谢你的指点!以这种方式实施是有意义的。
protected transient PropertyChangeSupport changeSupport = null;

public void addPropertyChangeListener (String propertyName, PropertyChangeListener listener)
{
    if (changeSupport == null)
        changeSupport = new PropertyChangeSupport (this);

    changeSupport.addPropertyChangeListener (propertyName, listener);
}

public void firePropertyChange (String propertyName, BigDecimal oldValue, BigDecimal newValue)
{
    if (changeSupport == null)
        return;

    if (oldValue != null && newValue != null && oldValue.compareTo (newValue) == 0) {
        return;
    }
    changeSupport.firePropertyChange(new PropertyChangeEvent(this, propertyName,
                                               oldValue, newValue));
}