Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность
Говоря оJava исходный код, я считаю, что у моих друзей есть более или менее контакт, например, общий ArrayList, HashMap, LinkedHashMap в пакете util и классы, связанные с многопоточностью, которые мы изучили ранее, такие как:Executors
,CountDownLatch
,CyclicBarrier
, или в пакете langObject
,Integer
,String
,Thread
Ждать.
Это наши более распространенные классы, но иногда мы не можем сказать, почему они реализованы.Некоторые люди даже пишут код в течение четырех или пяти лет, и они даже не видели, как реализован самый распространенный String.Я всегда жалуюсь, что Я всегда передвигаю кирпичи каждый день, и мое будущее потеряно. Честно говоря, изучение исходного кода заключается не только в том, чтобы иметь дело с интервью, но, что более важно, в процессе чтения исходного кода,изучите его дизайн-мышление, эту идею можно полностью реализовать в нашем проекте.
Таким образом, чтение исходного кода имеет следующие преимущества:
- Научитесь отличным дизайнерским идеям;
- Увеличьте силу интервью и подметайте все;
- Напрягите мышцы во время ежедневных обзоров кода.
Во-вторых, анализ исходного кода String.
Сначала посмотрите на небольшой пример:
String name = "huage";
name="huasao";
Я полагаю, что мы также столкнемся с проблемами типа [в этом процессе несколько объектов] в интервью.На самом деле, когда имя будет переназначено, оно не будет изменено в исходном адресе памяти, а будет создан новый объект, как показано на следующем рисунке.
2.1 Ненаследуемая причина 1: определение класса
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
...
}
В приведенном выше примере нам нужно проанализировать из кода, почему String является неизменяемым, мы можем видеть в определении класса String.java: класс String изменен с помощью ключевого слова final, что также означает, что класс String не может быть унаследован, после создания , его нельзя изменить.
Класс String также реализует три интерфейса:
- Сериализация: внедрение сериализации, отметьте интерфейс, который используется для идентификации сериализации и не может быть сериализован без реализации этого интерфейса.
- Comparable: Сравните размер двух созданных объектов.
- CharSequence: String по существу представляет собой массив символов, и этот интерфейс представляет собой последовательность символов, доступную только для чтения.
2.2 Ненаследуемая причина 2: переменные-члены
/** The value is used for character storage. */
private final char value[];
Данные, хранящиеся в String, представляют собой значение массива char, и значение также изменяется с помощью final, что означает, что массив нельзя изменить.
Но в это время некоторые друзья спросят: переменные, измененные final, являются неизменяемыми только по ссылке, а значение в куче памяти может быть полностью изменено.
final char value[] = {'h','u','a','g','e'};
value[4] = 's';
System.out.println(value); //最终输出:huags
В настоящее время мы должны взглянуть на это. сгенерировано.
2.3 Расширение: общие методы
Далее посмотрим, как реализованы несколько общих методов в классе String.
- equals
public boolean equals(Object anObject) {
//内存地址是否相同
if (this == anObject) {
return true;
}
//目标对象是否为String类,不是的话直接返回false
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
//判断两者长度是否相等
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
//比较两者中每一个字符是否相等
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
- Строка перехвата: подстрока
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);
}
Из приведенного выше исходного кода можно сделать вывод, что для начального/конечного индекса, который соответствует условиям, метод вызовет конструктор new String(), и конструктор, наконец, сгенерирует новую строку для возврата через System.arraycopy, которая означает, что этот метод не изменяет исходную строку.
Точно так же мы можем просмотреть исходный код таких методов, как replace и concat, Они не будут изменять исходную строку, но будут генерировать новый строковый объект для возврата, что также является неизменностью String.
Три, String неизменяемые преимущества
- сохранить память
Если определено несколько объектов и значение каждого объекта одинаково, на практике в динамической памяти будет храниться только одна копия данных, что позволит сократить накладные расходы памяти.
\