Как работает String Intern (C# против Java)? ⇐ C#
Как работает String Intern (C# против Java)?
Я знаю, что оптимизация интернирования строк есть как в C#, так и в Java.
Когда я пробую эти два кода с помощью Java:
public static void main(String[] args) { char p[]={'h','e','e','l','l','l','l'}; // Создаем строку из char[], чтобы убедиться, что она еще не интернирована Строка s1 = новая строка (p); Строка i1 = s1.intern(); System.out.println(s1== i1); // истинный } Код №2:
public static void main(String[] args) { char p[]={'h','e','e','l','l','l','l'}; // Создаем строку из char[], чтобы убедиться, что она еще не интернирована Строка s1 = новая строка (p); Строка i1 = s1.intern(); System.out.println(s1== i1); // истинный Строка o = "heellll"; System.out.println(o== i1); // истинный System.out.println(s1== o); // истинный } Однако, когда я пробую использовать те же два кода на C#:
unsafe static void Main(string[] args) { char[] p = { 'h', 'e', 'e', 'l', 'l', 'l', 'l' }; // Создаем строку из char[], чтобы убедиться, что она еще не интернирована Строка s1 = новая строка (p); Строка i1 = string.Intern(s1); Console.WriteLine(object.ReferenceEquals(s1, i1)); // Истинный } Код №2:
unsafe static void Main(string[] args) { char[] p = { 'h', 'e', 'e', 'l', 'l', 'l', 'l' }; // Создаем строку из char[], чтобы убедиться, что она еще не интернирована Строка s1 = новая строка (p); Строка i1 = string.Intern(s1); Console.WriteLine(object.ReferenceEquals(s1, i1)); // ЛОЖЬ Строка o = "heellll"; Console.WriteLine(object.ReferenceEquals(o, i1)); // Истинный Console.WriteLine(object.ReferenceEquals(s1, o)); // ЛОЖЬ } Я ожидаю двух разных сценариев и надеюсь, что один из этих сценариев покажет причину, по которой выходные данные кода C# (кодовый номер 2) не совпадают с выходными данными кода Java (кодовый номер 2): Мое первое ожидание: в C# среда CLR проверяет строковые литералы перед выполнением любой строки вашего кода, поэтому String o = "heellll"; выполняется перед запуском кода (так что String o = "heellll"; выполняется String s1 = new String(p); затем "heellll" добавляется в внутренний пул перед s1, поэтому при выполнении строки String i1 = string.Intern(s1); s1 не добавляется, а >string.Intern(s1); возвращает ссылку на "heellll"), с другой стороны (в Java) JVM не проверяет строковые литералы перед запуском любой строки в вашем код.
Мое второе ожидание: в C# для CLR приоритетом является сохранение ссылок на строковые литералы (CLR сохраняет ссылку s1 (в строке String i1 = string.Intern( s1);), но когда CLR находит строковые литералы, представляющие значение строкового объекта (s1) (в строке String o = "heellll";) CLR заменяет ссылку s1 (которая находится во внутреннем пуле) на эту ссылку на строковые литералы, но если CLR находит строковый объект, который представляет значение другого строкового объекта, CLR ничего не делает) , с другой стороны (в Java) для JVM сохранение ссылок на строковые литералы не является приоритетом.
Итак, какой сценарий является правильным? Если оба сценария неверны, то в чем причина того, что выходные данные кода C# (кодовый номер 2) не совпадают с выходными данными кода Java (кодовый номер 2)?
Я знаю, что оптимизация интернирования строк есть как в C#, так и в Java.
Когда я пробую эти два кода с помощью Java:
public static void main(String[] args) { char p[]={'h','e','e','l','l','l','l'}; // Создаем строку из char[], чтобы убедиться, что она еще не интернирована Строка s1 = новая строка (p); Строка i1 = s1.intern(); System.out.println(s1== i1); // истинный } Код №2:
public static void main(String[] args) { char p[]={'h','e','e','l','l','l','l'}; // Создаем строку из char[], чтобы убедиться, что она еще не интернирована Строка s1 = новая строка (p); Строка i1 = s1.intern(); System.out.println(s1== i1); // истинный Строка o = "heellll"; System.out.println(o== i1); // истинный System.out.println(s1== o); // истинный } Однако, когда я пробую использовать те же два кода на C#:
unsafe static void Main(string[] args) { char[] p = { 'h', 'e', 'e', 'l', 'l', 'l', 'l' }; // Создаем строку из char[], чтобы убедиться, что она еще не интернирована Строка s1 = новая строка (p); Строка i1 = string.Intern(s1); Console.WriteLine(object.ReferenceEquals(s1, i1)); // Истинный } Код №2:
unsafe static void Main(string[] args) { char[] p = { 'h', 'e', 'e', 'l', 'l', 'l', 'l' }; // Создаем строку из char[], чтобы убедиться, что она еще не интернирована Строка s1 = новая строка (p); Строка i1 = string.Intern(s1); Console.WriteLine(object.ReferenceEquals(s1, i1)); // ЛОЖЬ Строка o = "heellll"; Console.WriteLine(object.ReferenceEquals(o, i1)); // Истинный Console.WriteLine(object.ReferenceEquals(s1, o)); // ЛОЖЬ } Я ожидаю двух разных сценариев и надеюсь, что один из этих сценариев покажет причину, по которой выходные данные кода C# (кодовый номер 2) не совпадают с выходными данными кода Java (кодовый номер 2): Мое первое ожидание: в C# среда CLR проверяет строковые литералы перед выполнением любой строки вашего кода, поэтому String o = "heellll"; выполняется перед запуском кода (так что String o = "heellll"; выполняется String s1 = new String(p); затем "heellll" добавляется в внутренний пул перед s1, поэтому при выполнении строки String i1 = string.Intern(s1); s1 не добавляется, а >string.Intern(s1); возвращает ссылку на "heellll"), с другой стороны (в Java) JVM не проверяет строковые литералы перед запуском любой строки в вашем код.
Мое второе ожидание: в C# для CLR приоритетом является сохранение ссылок на строковые литералы (CLR сохраняет ссылку s1 (в строке String i1 = string.Intern( s1);), но когда CLR находит строковые литералы, представляющие значение строкового объекта (s1) (в строке String o = "heellll";) CLR заменяет ссылку s1 (которая находится во внутреннем пуле) на эту ссылку на строковые литералы, но если CLR находит строковый объект, который представляет значение другого строкового объекта, CLR ничего не делает) , с другой стороны (в Java) для JVM сохранение ссылок на строковые литералы не является приоритетом.
Итак, какой сценарий является правильным? Если оба сценария неверны, то в чем причина того, что выходные данные кода C# (кодовый номер 2) не совпадают с выходными данными кода Java (кодовый номер 2)?
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение