Класс String в объектах Java и использование нового ключевого слова [дубликат]

awk -v tgt=3 '
/^category$/ { fnd=1; rec="" }

fnd {
   rec = rec $0 ORS
   if (/^done$/) {
      if (++cnt == tgt) {
         printf "%s",rec
         exit
      }
      fnd = 0
   }
}
' file
149
задан Graham Borland 10 July 2013 в 00:04
поделиться

10 ответов

Java String Special

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

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

Например,

String s1 = "Hello";              // String literal
String s2 = "Hello";              // String literal
String s3 = s1;                   // same reference
String s4 = new String("Hello");  // String object
String s5 = new String("Hello");  // String object

enter image description here [/g2]

Примечание: Строковые литералы сохраняются в общий пул. Это облегчает совместное использование хранилищ для строк с одним и тем же содержимым для сохранения хранилища. String объекты, выделенные новым оператором, хранятся в heap, и нет совместного использования хранилища для того же содержимого.

287
ответ дан BlackBeard 22 August 2018 в 12:21
поделиться
  • 1
    Следует отметить, что "общий пул" обычно является частью кучи. – Joachim Sauer 5 July 2013 в 14:31
  • 2
    @JoachimSauer Да .. с небольшими преимуществами :) добавил, что в примечании. Спасибо за воспоминание. – ꜱᴜʀᴇꜱʜ ᴀᴛᴛᴀ 5 July 2013 в 14:39
  • 3
    Так что быстрее писать String s1 = & quot; Hello & quot ;; чем String s2 = new String («Привет») ;? – user2097804 5 July 2013 в 14:50
  • 4
    Я бы добавил, что в вашем примере s1 == s2 == s3, но s4! = S5 – Alfredo Osorio 5 July 2013 в 15:01
  • 5
    @AndrewJanke на недавнем hotspot jvm (7), пул строк не находится в perm gen, а с Java 8 больше нет perm gen ... – assylias 31 August 2013 в 07:14

Java рассматривает String как особый класс, вы можете инициализировать в обоих направлениях

  1. Прямо назначать литерал
    String a = "adsasdf";
    
  2. Как и другие объекты с использованием нового ключевого слова
    String a = new String("adsasdf");
    

Вам нужно проявлять особую осторожность, когда вы хотите сравнить с знаком ==:

String a = "asdf";
String b = "asdf";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True

String a = new String("asdf");
String b = new String("asdf");
System.out.println(a == b);  // False
System.out.println(a.equals(b)); // True

Это потому, что в первом случае сохраняются объекты a и b в том, что называется literal pool, и оба они ссылаются на один и тот же объект, поэтому они равны в обоих направлениях.

Но во втором случае a и b ссылаются на разные объекты, например, когда мы инициализируем любые другие объекты. поэтому они неравны по сравнению с == оператором, тогда как они равны по значениям.

47
ответ дан Grijesh Chauhan 22 August 2018 в 12:21
поделиться

String получает специальную обработку в JLS: это один из двух непримитивных типов, для которых существуют литералы (другой - Class ) *.

Из JLS :

Строковый литерал является ссылкой на экземпляр класса `String [...].

* ну, также есть «нулевой тип» с его «нулевым литералом» null, но большинство людей не думают о «нулевом типе» как правильном типе.

17
ответ дан Joachim Sauer 22 August 2018 в 12:21
поделиться
  • 1
    Я также не знал об этом «нулевом типе». является правильным типом в Java. Его очень полезная информация, вы должны увеличить размер шрифта. – Grijesh Chauhan 10 July 2013 в 06:55
  • 2
    @GrijeshChauhan: ну, нулевой тип " является просто отличной формулировкой, позволяющей присвоить любой null любой переменной ссылочного типа. Это не интересный тип, иначе. – Joachim Sauer 10 July 2013 в 07:09

Просто упомянем. Строковый литерал является ссылкой на экземпляр класса String, который вы можете написать следующим образом:

 "abc".getBytes();

 "a:b:c".split(":");

 "愛".codePointAt(0);
2
ответ дан mkdev 22 August 2018 в 12:21
поделиться

Это особенность языка Java. Строковые литералы в исходном коде получают специальную обработку.

Спецификация языка здесь просто говорит, что строковый литерал имеет тип String

15
ответ дан nos 22 August 2018 в 12:21
поделиться

- String является классом в Java . Вы правы в этом, поэтому мы всегда можем инициализировать ключевое слово new.

- Но когда мы делаем что-то вроде:

String s = "";

Вышеупомянутый оператор отмечен компилятором как особый объект String, а затем JVM во время загрузки класса (загрузка выполняется до инициализации), видит это, как известно, как строковый литерал, который хранится в пуле строковых литералов.

. Таким образом, String может быть создана с использованием new() и методом "", но последняя предоставляет строковый литерал, который остается в куче, даже если нет ссылки на этот строковый объект, поскольку он имеет ссылку из пула строковых литералов.

2
ответ дан Peter Mortensen 22 August 2018 в 12:21
поделиться

Строки очень часто используются на языке программирования. Поскольку java объектно-ориентированная строка является объектом. Чтобы избежать громоздкой новой String («someString»); оператор каждый раз, когда вам нужен строковый объект java, вы можете просто создать строковый объект, используя строковый литерал.

Но вы должны иметь в виду равенство строк. Здесь короткий тест JUnit, чтобы продемонстрировать, что я имею в виду.

    @Test
    public void stringTest() {
       // a string literal and a string object created 
       // with the same literal are equal
       assertEquals("string", new String("string"));

       // two string literals are the same string object
       assertSame("string", "string"); 

       // a string literal is not the same object instance 
       // as a string object created with the same string literal
       assertFalse("string" == new String("string"));

       // java's String.intern() method gives you the same
       // string object reference for all strings that are equal.
       assertSame("string", new String("string").intern());
    }
4
ответ дан René Link 22 August 2018 в 12:21
поделиться
  • 1
    Если вы могли бы инициализировать строку только с помощью new String(String src), вы даже не смогли бы дать конструктору строковый литерал. Вам нужно будет инициализировать char [], а затем использовать конструктор String(char [] src) для построения строки или вам нужно будет прочитать строку из файла. – AJMansfield 5 July 2013 в 14:48
  • 2
    Это неверно. Строковый литерал - это только символьная последовательность в исходном файле, окруженная двойными кавычками. Java автоматически создает экземпляр строки, используя этот литерал. Таким образом, литерал и объект String равны, но они не совпадают. Java также может быть реализована таким образом, что вы должны использовать новую строку String (& quot;); для создания объекта String, но это только усложнит нашу жизнь. Поэтому, когда вы пишете новую строку («строка»), java создает объект String для литерала «строка», и передает этот строковый объект в конструктор новой String. – René Link 17 July 2013 в 10:52

Java.lang.String - это не просто класс. Это неотъемлемая часть основного языка. У компилятора есть синтаксический сахар. Например, "" является аббревиатурой для new String(""). Когда написано "", компилятор оптимизирует идентичные строки для одного и того же экземпляра, чтобы сэкономить место. "a" + 5 == "a5" ==> true

У компилятора есть синтаксический сахар для большого количества материала, в том числе нечего делать в ящик / unbox между объектными версиями и их родными типами, без родительских средств Object, конструктор по умолчанию, ...

1
ответ дан Sylwester 22 August 2018 в 12:21
поделиться
  • 1
    "" не является аббревиатурой для new String(""). Если вы используете "", первое, что будет сделано, это поиск совпадений в пуле String JVM, и если это правда, он вернет эту строку. Используя new String(""), вы всегда будете создавать новую строку, даже если сама строка уже существует в пуле String (потому что она не будет сохранена в пуле строк). – g00glen00b 5 July 2013 в 14:02
  • 2
    Я обновил свой ответ. Используют ли они это в своих интересах, например, используя строковые константы, эквивалентные типу символов Lisp? – Sylwester 6 July 2013 в 19:14

Текст внутри двойных кавычек создает объект литерала String.

String myString = "Some text";

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

5
ответ дан tristan2468 22 August 2018 в 12:21
поделиться

Java выполняет для нас двухэтапный процесс.

String str = "hello";

эквивалентен

char data[] = {'h', 'e', 'l' , 'l', 'o'};
String str = new String(data);

Подобно [.NET] [1], получил аналогичную вещь.

String(Char[]) constructor

делает

String(char[] value)

Добавление ссылок: -

2
ответ дан ꜱᴜʀᴇꜱʜ ᴀᴛᴛᴀ 22 August 2018 в 12:21
поделиться
  • 1
    @Peter Mortensen благодарит за изменения – user1769790 6 July 2013 в 00:32
  • 2
    Процесс, который вы описываете, не то, что на самом деле выполняет Java. Как уже отмечали другие, "hello" является строковым литералом и будет помещен в пул констант компилятором, см. JLS §3.10.5 и JVMS §5.1 . – siegi 10 July 2013 в 23:43
Другие вопросы по тегам:

Похожие вопросы: