Подтвердить что ты не робот

Строка s = новая строка ( "xyz" ). Сколько объектов было сделано после выполнения этой строки кода?

Общепринятый ответ на этот вопрос интервью состоит в том, что код создает два объекта. Но я так не думаю; Я написал код для подтверждения.

public class StringTest {
    public static void main(String[] args) {
        String s1 = "a";
        String s2 = "a";
        String s3 = new String("a");
        System.out.println("s1: "+s1.hashCode());
        System.out.println("s2: "+s2.hashCode());
        System.out.println("s3: "+s3.hashCode());
    }
}

Вывод:

Application output

Означает ли это, что был создан только один объект?

Подтвердите: мой вопрос: сколько объектов было создано с помощью следующего кода:

String s = new String("xyz")

Вместо кода StringTest.

Вдохновленный @Don Branson, я отлаживал приведенный ниже код:

public class test {
    public static void main(String[] args) {
        String s = new String("abc");
    }
}

И результат:

Enter image description here

Идентификатор s равен 84, а идентификатор "abc" равен 82. Что именно это означает?

4b9b3361

Ответ 1

ОШИБКИ НИЖЕ ЗАВИСИМО ОТ JVM/JRE, КОТОРЫЕ ВЫ ИСПОЛЬЗУЕТЕ. ЭТО ЛУЧШЕ, ЧТОБЫ НЕ МОЖЕТ БЫТЬ ОБРАБОТАТЬ О ВЕЩИ, КАК ЭТО ВЕРОЯТНО. СМ. ЗАМЕЧАНИЯ РАЗДЕЛА ДЛЯ ЛЮБЫХ ИСПРАВЛЕНИЙ/КОНЦЕРН.

Во-первых, этот вопрос действительно спрашивает об этом здесь: Является ли String Literal Pool набор ссылок на объект String или набор объектов

Итак, это руководство для всех по этому вопросу.

...

С учетом этой строки кода: String s = new String("xyz")

Есть два способа взглянуть на это:

(1) Что происходит, когда выполняется строка кода - буквальный момент, который он запускает в программе?

(2) Каков чистый эффект от того, сколько Objects создано оператором?

Ответ:

1) После этого создается один дополнительный объект.

a) "xyz" String создается и интернируется, когда JVM загружает class, в котором содержится эта строка кода.

  • Если "xyz" уже находится в основном пуле из какого-либо другого кода, тогда литерал не может создать новый объект String.

b) Когда создается новый String s, внутренний char[] является копией интернированной строки "xyz".

c) Это означает, что когда строка выполняется, создается только один дополнительный объект.

Дело в том, что объект "xyz" будет создан, как только загрузится класс, и до того, как этот раздел кода будет запущен.

... следующий сценарий...

2) Существует три объекта, созданных кодом (включая интернированный "a")

String s1 = "a";
String s2 = "a";
String s3 = new String("a");

a) s1 и s2 просто ссылаются, а не объекты, и они указывают на то же самое String в памяти.

b) "a" интернирован и представляет собой составной объект: один объект char[] и сам объект String. Он состоит из двух объектов в памяти.

c) s3, new String("a") создает еще один объект. Новый String("a") не копирует char[] слова "a", он ссылается только на него. Вот подпись метода:

public String2(String original) {
        this.value = original.value;
        this.hash = original.hash;
}

Один интернированный String ("a") равен 2 Objects. И один new String("a") равен еще одному объекту. Чистый эффект от кода - это три объекта.

Ответ 2

Для этого создаются два объекта:

String s = new String("abc");

Один в куче, а другой в "пуле строковых констант" (SCP). Ссылка s всегда будет указывать на s, а GC не разрешена в области SCP, поэтому все объекты в SCP будут автоматически уничтожены во время отключения JVM.

Например:

Здесь, используя ссылку на объект кучи, мы получаем соответствующую ссылку объекта SCP путем вызова intern()

String s1 = new String("abc");
String s2 = s1.intern(); // SCP object reference
System.out.println(s1==s2); // false
String s3 = "abc";
System.out.println(s2==s3); //True s3 reference to SCP object here

Ответ 3

Существует два способа создания строковых объектов в Java:

  • Используя новый оператор, т.е.

    String s1 = new String("abc");
    
  • Использование строкового литерала, т.е.

    String s2 = "abc";
    

Теперь распределение строк является дорогостоящим как во времени, так и в памяти, поэтому JVM (Java Virtual Machine) выполняет некоторые задачи. ЧТО ЗАДАЕТСЯ?

Смотрите, всякий раз, когда вы используете оператор new, объект создается, а JVM не будет выглядеть в пуле строк. Он просто собирается создать объект, но когда вы используете строковые литералы для создания строковых объектов, JVM выполнит задачу поиска в пуле строк

I.e., когда вы пишете

String s2 = "abc";

JVM будет выглядеть в пуле строк и проверять, существует ли "abc" или нет. Если он существует, возвращается ссылка на уже существующую строку "abc", и новый объект не создается, а если он не существует, создается объект.

Итак, в вашем случае (А)

String s1 = new String("abc");
  • Так как используется new, объект создается

(б)

String s2 = "abc";
  • с использованием строкового литерала создается объект, а "abc" не находится в пул строк и, следовательно, объект создан.

(с)

String s2 = "abc";
  • Опять же, используя строковый литерал, а "abc" - в пуле строк и поэтому объект не создается.

Вы также можете проверить это, используя следующий код:

class String_Check
{
    public static void main(String[] n)
    {
        String s1 = new String("abc");
        String s2 = "abc";
        String s3 = "abc";
        if (s1==s2)
            System.out.println("s1==s2");
        if(s1==s3)
            System.out.println("s1==s3");
        if(s2==s3)
            System.out.println("s2==s3");
    }
}

Надеюсь, это поможет... Обратите внимание, что == используется, чтобы видеть, равны ли объекты, и метод equals(Object) используется, чтобы увидеть, соответствуют ли контент.

Ответ 4

  1. String s = новая строка ("xyz");

Приведенная выше строка создаст два объекта: один находится в куче, а другой - в пуле констант String.

теперь, если мы сделаем это

  1. String s = new String("xyz");
  2. String s1 ="xyz";

вышеприведенные два утверждения создадут два объекта. Первая строка String s = new String("xyz"); создаст два объекта, как указано в 1-й строке и, когда String s = "xyz"; выполняет его, проверяет в пуле строковых констант, есть ли там тот же объект содержимого, или нет, так как первая строка сделала запись в пуле строковых констант с помощью "xyz", он возвращает ту же ссылку и не создает другой объект.

Что делать, если у нас есть эти четыре линии вместе, как упоминалось ниже.

  1. String s2 = new String("xyz");
  2. String s3 ="xyz";
  3. String s4 = new String("xyz");
  4. String s5 ="xyz";

Если мы выполним вышеуказанную строку, у нас будет три объекта.

  • Первый и, как уже упоминалось, создадут два объекта, один в куче, а другой в строковом постоянном опросе.
  • Когда вторая строка выполняется, она проверяет строковую константу poll
    и найти с помощью "xyz", чтобы он возвращал один и тот же объект, так что до второй строки у нас есть два объекта.
  • когда третья строка будет выполнена, она создаст новый объект в куче, поскольку оператор new создает объект в куче, поэтому до третьей строки будет 3 объекта.
  • Когда выполняется четвертая строка, она проверяет строковую константу poll
    и найти с помощью "xyz", чтобы он возвращал один и тот же объект, поэтому в четвертой строке у нас есть три объекта.

Бонус о методе intern()

Когда метод intern() вызывается для объекта String, он ищет строку, содержащуюся в этом объекте String, в пуле, если строка находится там, возвращается строка из пула. В противном случае этот объект String добавляется в пул и возвращается ссылка на этот объект String.

public class TestString {

    public static void main(String[] args) {
        String s1 = "Test";
        String s2 = "Test";
        String s3 = new String("Test");
        final String s4 = s3.intern();
        System.out.println(s1 == s2);
        System.out.println(s2 == s3);
        System.out.println(s3 == s4);
        System.out.println(s1 == s3);
        System.out.println(s1 == s4);
        System.out.println(s1.equals(s2));
        System.out.println(s2.equals(s3));
        System.out.println(s3.equals(s4));
        System.out.println(s1.equals(s4));
        System.out.println(s1.equals(s3));
    }

}

Ответ 5

Если мы выполним String s = new String("Brajesh"); должны быть созданы два объекта. Один объект будет создан в строковом литерале, а другой - в области кучи. Но если у нас уже есть тот же строковый литерал объекта, то создается только один объект. лайк

String s1  ="Brajesh"; 
String s = new String("Brajesh");//it will create only one object in heap area

Помимо этого еще один дополнительный объект также создается в области кучи, который является объектом char []. Я приложил здесь снимок кучи памяти. enter image description here

Ответ 6

Создаются 2 или 3 объекта, в зависимости от того, насколько интеллектуальным является компилятор.

Тем не менее, ваш тест неактивен, потому что hashCode of String основан на содержимом String, а не на их идентификаторе. Если вы хотите проверить личность, вы должны использовать сравнение System.identityHashCode или просто ==.

Компилятор и среда выполнения разрешены (не принудительно) для оптимизации создания строк, когда это возможно. Таким образом, они оптимизируют литеральные строки, используя один литерал для трех строк, которые у вас есть. Во всяком случае, оператор new должен возвращать новый объект (т.е. Недавно выделенный). Оптимизация строк во время выполнения возможна, если вместо этого используется статический метод String.valueOf. Но я не знаю, действительно ли какое-либо кэширование применяется существующими JRE (возможно, более дорого проверить хэш-таблицу, чем просто выделить новый String)

Ответ 7

java.lang.String переопределяет метод hashCode(), так что значение зависит от содержимого строки.

В результате hashCode() ничего не говорит о количестве экземпляров. Это может быть одна и та же строка или может быть другим экземпляром без общего байта. То же о equals(). Это объясняет ваш результат.

Используйте System.identityHashCode(..) для такого рода исследований.

И может быть источник с вами.

Ответ 8

        String s1="Pune";
        String s2="Mumbai";
        String s3="Pune";
        String s4=new String("Mumbai");
        System.out.println("S1 :"+s1.hashCode());  //S1 :2499228
        System.out.println("S2 :"+s2.hashCode());  //S2 :-1979126203
        System.out.println("S3 :"+s3.hashCode());  //S3 :2499228
        System.out.println("S4 :"+s4.hashCode());  //S4 :-1979126203
        System.out.println(s2==s4);     // false

Как мы видим в приведенной выше программе, мы получаем одинаковый хэш-код для s2 и s4, хотя мы получаем false с помощью оператора ==. == используется для сравнения ссылок.

В "String s4 = new String (" Mumbai ") были созданы два объекта: один в кучевой памяти и один в стеке. Поэтому s2 сравнивается с s4, который создается в куче памяти, а не с памятью стека.

Ответ 9

public String(String original) {
    int size = original.count;
    char[] originalValue = original.value;
    char[] v;
    if (originalValue.length > size) {
        // The array representing the String is bigger than the new
        // String itself.  Perhaps this constructor is being called
        // in order to trim the baggage, so make a copy of the array.
        int off = original.offset;
        v = Arrays.copyOfRange(originalValue, off, off+size);
    } else {
        // The array representing the String is the same
        // size as the String, so no point in making a copy.
        v = originalValue;
    }
    this.offset = 0;
    this.count = size;
    this.value = v;
}

Если мы увидим код, мы увидим, что он просто создаст char [], и он будет каждый раз копироваться с тем же контентом, который будет создан, и да, он будет хранить данные в String Constant Pool. 1) Возьмем из SCP String s1 = "a" String s2 = "a"; 2) Создает новый объект String s3 = new String ( "a" ); Curiosity, New Object String s2 = new String ( "a" ); Во всем выше кода тот же char [] получит copied.i: e char [] значение Вы можете проверить здесь

Ответ 10

Если мы запустим приведенный ниже код в eclipse в режиме отладки, мы получим представление о том, сколько объектов создано с помощью String string = new String("manoj"); Внутренне он создаст String str = "manoj" в конструкторе класса String. Просто проверьте идентификатор после наведения на ссылку, как показано на снимке экрана ниже. Скриншот

public static void main(String[] args)
{
    String str = "atul";
    String string = new String("manoj");
    String string2 = "manoj";
    System.out.println(str == string);
}

Ответ 11

Запутавшись в том, что именно происходит после вызова новой строки ("<>"), я нашел эту тему. Ваше понимание сравнения хэш-кода не является технически правильным, хотя.

int hashCode() был переопределен в классе String, и он возвращает значение в зависимости от содержимого литерала String.

String s1 = new String ("Hello"); String s2 = new String ("Hello");

Итак, s1.hashCode() = s2.hashCode() = anyStringOfContent_ "Hello".hashCode()

**/** Cache the hash code for the string */
private int hash; // Default to 0
public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;
        for (int i = 0; i < value.length; i++) {
            **h = 31 * h + val[i];**
        }
        hash = h;
    }
    return h;
}**

Теперь, чтобы просто объяснить, почему это сделано, вы можете прочитать книгу Кэти Сьерра, в которой есть отличное объяснение, почему разработчики поступили таким образом (в основном любые объекты, возвращающие true в метод equals(), должны возвращать то же значение hashCode()).

Ответ 12

Если new String() создает 2 объекта (один в куче и один в пуле строк), то какой метод .intern используется?

Метод intern(), вызываемый для объекта String, ищет строку, содержащуюся в этом объекте String, в пуле. Если строка находится там, возвращается строка из пула. В противном случае этот объект String добавляется в пул и возвращается ссылка на этот объект String.

Ответ 13

Я запустил его в отладчике Eclipse. В этом контексте создаются два объекта: один с идентификатором 17, другой 22:

enter image description here

Ответ 14

@Giulio, Вы правы. String s3 = new String ( "abc" ); создает два объекта один в куче со ссылкой s3 и другой в SCP (без ссылки). и теперь String s2 = "abc" ; не создает никакого нового объекта в SCP, потому что "abc" уже присутствует в SCP.

    String s1 = "abc";
    String s2 = "abc";
    String s3 = new String("abc");
    String s4 = s3.intern();
    System.out.println("s1: "+System.identityHashCode(s1));
    System.out.println("s2: "+System.identityHashCode(s2));
    System.out.println("s3: "+System.identityHashCode(s3));
    System.out.println("s4: "+System.identityHashCode(s4));

O/P: s1: 366712642,   s2: 366712642,   s3: 1829164700,   s4: 366712642

Поскольку я не могу комментировать, я написал его здесь.

Ответ 15

В Java существует концепция, называемая пулом строк. Пул строк (пул строк) - это специальная область хранения в куче Java. Когда создается строка и если строка уже существует в пуле, будет возвращена ссылка на существующую строку вместо создания нового объекта и возврата его ссылки.

Итак String s = new String("xyz") он создаст два объекта.

  • Первый объект будет создан в постоянной памяти кучи Java как часть аргумента, который мы передаем, - "XYZ". И он будет создан в пуле строк String.

  • Второй объект будет создан в памяти кучи Java, который будет создан как часть оператора new.

Ответ 16

String s = новая строка ("xyz");

сколько объектов было создано в приведенном выше коде?

В приведенном выше коде был создан только один объект, который находится в куче памяти.

не два объекта.....

Если два объекта созданы, один находится в динамической памяти (оператор new), а другой - в пуле String (строковый литерал), если ваше хранилище ниже значения с использованием литерала String,

Строка s1 = "xyz";

он не будет возвращать ссылку на объект s в пуле строковых констант. он создаст новый объект в String Constant Pool как s1.

Как?

мы можем проверить это с помощью оператора == (s == s1), чтобы проверить тип ссылки. Если s уже хранится в пуле строковых констант, он выдает true, в этом случае вывод ложен.

Таким образом, вывод заключается в том, что один объект создан в приведенном выше коде.

Ответ 17

Просто потому, что все ваши хэш-коды одинаковы, это не значит, что вы смотрите на один и тот же объект. Создаются два объекта. Пусть это сломается.

String s = new String("xyz");

В части 'new String ( "xyz" ) адрес возвращается к новой строке "xyz". Когда вы говорите "String s =", это присваивает возвращенный адрес этому объекту, чтобы они указывали на одно и то же место, но новая строка и строка s являются двумя отдельными объектами.

Ответ 18

Я использовал метод hashcode() для поиска числа созданных строковых объектов. Метод hashcode() пересказывает данные, хранящиеся в ссылочной переменной, в одно значение хэша.

case1:

String s="

Fred";
System.out.println(s.hashCode());

s=s+"47";
System.out.println(s.hashCode());

s=s.substring(2,5);
System.out.println(s.hashCode());

s=s.toUpperCase();
System.out.println(s.hashCode());

s=s.toString();
System.out.println(s.hashCode());

Вывод:

Fred--2198155         //1st object ----------------  String s="Fred"

Fred47--2112428622    //2nd object ----------------  s=s+"47"

ed4--100213           //3rd object ----------------  s=s.substring(2,5)

ED4--68469            //4th object ----------------  s=s.toUpperCase()

ED4--68469            //this is retrieved from the string constant pool -------- s=s.toString();

Так создано всего 4 объекта.

CASE 2:

String s="FRED";
System.out.println(s.hashCode());

s=s+"47";
System.out.println(s.hashCode());

s=s.substring(2,5);
System.out.println(s.hashCode());

s=s.toUpperCase();
System.out.println(s.hashCode());

s=s.toString();
System.out.println(s.hashCode());

Вывод:

FRED--2166379       //1st object ----------------  String s="Fred" 

FRED47--2081891886  //2nd object ----------------  s=s+"47"

ED4--68469          //3rd object ----------------  s=s.substring(2,5)

ED4--68469          //this is retrieved from the string constant pool -------  s=s.toUpperCase()

ED4--68469          //this is retrieved from the string constant pool -------- s=s.toString() 

Всего создано 3 объекта.

Ответ 19

Существует способ найти, сколько объектов создается с помощью ключевого слова new (String s1=new String("Rajesh")).

public class Rajesh {
    public static void main(String[] args){
        String s1=new String("Rajesh");
        System.out.println(s1+s1.intern());
    }
}

Вывод:

RajeshRajesh //s1=Rajesh+s2.intern()=Rajesh

Примечание. Поскольку мы знаем, что метод intern всегда попадает в строковый постоянный пул памяти кучи.