2013-07-08 27 views
1

为什么下面的代码会产生一个很好的ClassCastException异常:ClassCastException异常带的StringBuilder和CharSequence的

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

,而下面的代码(替换用字符串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)强制转换不起作用,而与字符串工作。

在此先感谢。

回答

7

这是因为StringBuilder.subSequence返回实际类是字符串:

... 
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); 
} 

你不能施放字符串的StringBuilder。

1

StringBuilder.subSequence API文档:

形式的该方法的调用

sb.subSequence(begin, end) 

的行为以完全相同的方式调用

sb.substring(begin, end) 

虽然StringCharSequenceString不是StringBuilder。所以演员失败了。

你可以这样做,而不是:

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

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

声明返回类型的方法必须是超类型返回对象的实际运行时类型。你很幸运能够投入正确的类型。

1

因为subSequence()方法在运行时返回String对象,而不是StringBuilder对象。根据文档StringBuilder#subSequence()

返回一个新的字符序列,该序列是该序列的子序列。 形式

sb.subSequence的此方法的调用(开始,结束) 的行为以完全相同的方式调用

某人。子(开始,结束)

如果你经过这里的代码:

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。而你不能转换StringStringBuilder