StringBuilder和CharSequence的ClassCastException

时间:2013-07-08 08:25:26

标签: java string stringbuilder charsequence

为什么下面的代码会产生一个很好的ClassCastException:

public static void main(String []args){
        StringBuilder s1 = new StringBuilder("quaqua");
        StringBuilder s12= (StringBuilder)s1.subSequence(0,3);
        System.out.println(s12);
     }

而下面的代码(用String替换StringBuilder):

public static void main(String []args){
        String s1 = new String("quaqua");
        String s12= (String)s1.subSequence(0,3);
        System.out.println(s12);
     }

工作正常吗?

我知道有方法substring(int begin, int end);但是我很好奇为什么使用StringBuilder(实现CharSequence)的强制转换不起作用而使用String工作。

提前致谢。

4 个答案:

答案 0 :(得分:7)

这是因为StringBuilder.subSequence返回的实际类是String:

...
public CharSequence subSequence(int start, int end) {
    return substring(start, end);
}

public String substring(int start, int end) {
    ...
    return new String(value, start, end - start);
}

您无法将String强制转换为StringBuilder。

答案 1 :(得分:1)

StringBuilder.subSequence的API文档中:

  

调用

形式的此方法
sb.subSequence(begin, end)
     

的行为方式与调用

完全相同
sb.substring(begin, end)

虽然StringCharSequence,但String不是StringBuilder。所以演员阵容失败了。

您可以这样做:

StringBuilder s12= new StringBuilder(s1);
s12.setLength(3);

答案 2 :(得分:1)

因为subSequence()方法在运行时返回String对象而不是StringBuilder对象。根据{{​​3}}

的文档
  

返回一个新的字符序列,它是该序列的子序列。   调用

形式的此方法      

sb.subSequence(开始,结束)   行为与调用

完全相同      

sb.substring(开始,结束)

如果你在这里查看代码:

public CharSequence subSequence(int beginIndex, int endIndex) {
    return this.substring(beginIndex, endIndex);
}

如果您看到substring()的代码:

public String substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if (endIndex > value.length) {
        throw new StringIndexOutOfBoundsException(endIndex);
    }
    int subLen = endIndex - beginIndex;
    if (subLen < 0) {
        throw new StringIndexOutOfBoundsException(subLen);
    }
    return ((beginIndex == 0) && (endIndex == value.length)) ? this
            : new String(value, beginIndex, subLen);
}

它返回String,因为String实现了CharSequence接口,subSequence()的返回类型可以是CharSequence的返回类型,但是它在内部工作时String。并且您无法String投射到StringBuilder

答案 3 :(得分:0)

方法String.subSequence必须返回运行时类型String的对象,它只是实现CharSequence类型。

声明的返回类型的方法必须是返回对象的实际运行时类型的超类型您很幸运能够转换为正确的类型。