为什么要按原样定义SpannableString相等性?

问题描述

请考虑以下测试:

    @Test
    fun test() {
        val s1 = SpannableString("Test")
        val s2 = SpannableString("Test")
        s1.setSpan(StyleSpan(BOLD),s1.length,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        s2.setSpan(StyleSpan(BOLD),s2.length,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)

        assertEquals(s1,s2)
    }

它成功还是失败?

我的假设是它应该成功,但是失败(抓挠头)。在查看SpannableStringInternal的实现时,我们看到该函数将每个范围与其对应范围进行比较(假设我们具有相等数量的范围)。

 // Same as SpannableStringBuilder
    @Override
    public boolean equals(Object o) {
        if (o instanceof Spanned &&
                toString().equals(o.toString())) {
            final Spanned other = (Spanned) o;
            // Check span data
            final Object[] otherSpans = other.getSpans(0,other.length(),Object.class);
            final Object[] thisspans = getSpans(0,length(),Object.class);
            if (mSpanCount == otherSpans.length) {
                for (int i = 0; i < mSpanCount; ++i) {
                    final Object thisspan = thisspans[i];
                    final Object otherSpan = otherSpans[i];
                    if (thisspan == this) {
                        if (other != otherSpan ||
                                getSpanStart(thisspan) != other.getSpanStart(otherSpan) ||
                                getSpanEnd(thisspan) != other.getSpanEnd(otherSpan) ||
                                getSpanFlags(thisspan) != other.getSpanFlags(otherSpan)) {
                            return false;
                        }
                    } else if (!thisspan.equals(otherSpan) ||
                            getSpanStart(thisspan) != other.getSpanStart(otherSpan) ||
                            getSpanEnd(thisspan) != other.getSpanEnd(otherSpan) ||
                            getSpanFlags(thisspan) != other.getSpanFlags(otherSpan)) {
                        return false;
                    }
                }
                return true;
            }
        }
        return false;
    }

else if中的第一个条件比较了Span对象是否相等,并且样式跨度(尽管编码相同的数据且类型相同)不相等,因为看起来StyleSpan确实不覆盖等于。

为什么没有将这两者视为相等的特定原因,或者这是Android中的错误

解决方法

由于StyleSpan(BOLD),它没有通过。 if(thisSpan == this)是false,因为equals中没有覆盖StyleSpan。出于相同的原因,!thisSpan.equals(otherSpan)true(if-else的第一个条件),因此是return false。尝试将StyleSpan(BOLD)分配给val,并将相同的引用传递给两个SpannableStringBuilder。它应该通过

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...