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
Разработчики Java решили сохранить примитивные типы в объектно-ориентированном языке, вместо того чтобы сделать все объектом, чтобы улучшить работу языка. Примитивы хранятся в стеке вызовов, которые требуют меньше пространства для хранения и дешевле манипулировать. С другой стороны, объекты хранятся в куче программ, которые требуют сложного управления памятью и большего объема пространства для хранения.
По соображениям производительности, строка Java предназначена для того, чтобы находиться между примитивным и классом.
blockquote>Например,
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
[/g2]
Примечание: Строковые литералы сохраняются в общий пул. Это облегчает совместное использование хранилищ для строк с одним и тем же содержимым для сохранения хранилища.
String
объекты, выделенные новым оператором, хранятся вheap
, и нет совместного использования хранилища для того же содержимого.
Java рассматривает String как особый класс, вы можете инициализировать в обоих направлениях
String a = "adsasdf";
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 ссылаются на разные объекты, например, когда мы инициализируем любые другие объекты. поэтому они неравны по сравнению с ==
оператором, тогда как они равны по значениям.
String получает специальную обработку в JLS: это один из двух непримитивных типов, для которых существуют литералы (другой - Class
) *.
Из JLS :
Строковый литерал является ссылкой на экземпляр класса `String [...].
blockquote>* ну, также есть «нулевой тип» с его «нулевым литералом»
null
, но большинство людей не думают о «нулевом типе» как правильном типе.
null
любой переменной ссылочного типа. Это не интересный тип, иначе.
– Joachim Sauer
10 July 2013 в 07:09
Просто упомянем. Строковый литерал является ссылкой на экземпляр класса String, который вы можете написать следующим образом:
"abc".getBytes(); "a:b:c".split(":"); "愛".codePointAt(0);
Это особенность языка Java. Строковые литералы в исходном коде получают специальную обработку.
Спецификация языка здесь просто говорит, что строковый литерал имеет тип String
- String является классом в Java . Вы правы в этом, поэтому мы всегда можем инициализировать ключевое слово new
.
- Но когда мы делаем что-то вроде:
String s = "";
Вышеупомянутый оператор отмечен компилятором как особый объект String, а затем JVM во время загрузки класса (загрузка выполняется до инициализации), видит это, как известно, как строковый литерал, который хранится в пуле строковых литералов.
. Таким образом, String может быть создана с использованием new()
и методом ""
, но последняя предоставляет строковый литерал, который остается в куче, даже если нет ссылки на этот строковый объект, поскольку он имеет ссылку из пула строковых литералов.
Строки очень часто используются на языке программирования. Поскольку 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());
}
new String(String src)
, вы даже не смогли бы дать конструктору строковый литерал. Вам нужно будет инициализировать char []
, а затем использовать конструктор String(char [] src)
для построения строки или вам нужно будет прочитать строку из файла.
– AJMansfield
5 July 2013 в 14:48
Java.lang.String
- это не просто класс. Это неотъемлемая часть основного языка. У компилятора есть синтаксический сахар. Например, ""
является аббревиатурой для new String("")
. Когда написано ""
, компилятор оптимизирует идентичные строки для одного и того же экземпляра, чтобы сэкономить место. "a" + 5 == "a5" ==> true
У компилятора есть синтаксический сахар для большого количества материала, в том числе нечего делать в ящик / unbox между объектными версиями и их родными типами, без родительских средств Object, конструктор по умолчанию, ...
""
не является аббревиатурой для new String("")
. Если вы используете ""
, первое, что будет сделано, это поиск совпадений в пуле String JVM, и если это правда, он вернет эту строку. Используя new String("")
, вы всегда будете создавать новую строку, даже если сама строка уже существует в пуле String (потому что она не будет сохранена в пуле строк).
– g00glen00b
5 July 2013 в 14:02
Текст внутри двойных кавычек создает объект литерала String
.
String myString = "Some text";
Код выше создает объект String
, используя двойные кавычки.
Java выполняет для нас двухэтапный процесс.
String str = "hello";
эквивалентен
char data[] = {'h', 'e', 'l' , 'l', 'o'};
String str = new String(data);
Подобно [.NET] [1], получил аналогичную вещь.
String(Char[]) constructor
делает
String(char[] value)
Добавление ссылок: -
"hello"
является строковым литералом и будет помещен в пул констант компилятором, см. JLS §3.10.5 и JVMS §5.1 .
– siegi
10 July 2013 в 23:43