2013-07-08 1 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 с String):

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 работает.

Заранее спасибо.

ответ

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

В API Документов StringBuilder.subSequence:

Вызов этого метода формы

sb.subSequence(begin, end) 

ведет себя точно так же, как вызов

sb.substring(begin, end) 

Хотя String - CharSequence, String не является 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. И вы не может литой String до StringBuilder.

 Смежные вопросы

  • Нет связанных вопросов^_^