Строки Java: “Представьте s в виде строки = новая Строка (” глупый “)”;

84
задан vaxquis 14 January 2016 в 20:43
поделиться

15 ответов

String специальный встроенный класс языка. Это для String класс [только 119], в которых необходимо постараться не говорить

String s = new String("Polish");

, поскольку литерал "Polish" уже имеет тип String, и Вы создаете дополнительный лишний объект. Для любого другого класса, говоря

CaseInsensitiveString cis = new CaseInsensitiveString("Polish");

корректное (и только, в этом случае) вещь сделать.

108
ответ дан Adam Rosenfield 24 November 2019 в 08:26
поделиться

В большинстве версий JDK эти две версии будут тем же:

Строка s = новая ("глупая") Строка;

Строка s = "Больше глупый";

, поскольку строки неизменны, компилятор ведет список строковых констант и при попытке сделать новый, то сначала проверит, чтобы видеть, определяется ли строка уже. Если это - тогда ссылка на существующую неизменную строку, возвращается.

Для разъяснения - при высказывании "Строки s =" Вы определяете новую переменную, которая занимает место на стеке - тогда, не говорите ли Вы "Больше глупую" или новую Строку ("глупую") точно, то же самое происходит - новая постоянная строка компилируется в Ваше приложение и контрольные точки к этому.

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

ОБНОВЛЕНИЕ: Я был неправ! На основе вниз голосование и комментарий присоединили, я протестировал это, и поймите, что мое понимание является неправильным - новая ("Глупая") Строка действительно создает новую строку, а не снова использует существующую. Я неясен, почему это было бы (каково преимущество?), но код говорит громче, чем слова!

0
ответ дан Ewan Makepeace 24 November 2019 в 08:26
поделиться

Я просто добавил бы, что Java имеет конструкторы Копии ...

ну, это - обычный конструктор с объектом того же типа как аргумент.

0
ответ дан PhiLho 24 November 2019 в 08:26
поделиться

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

String s = "Polish";

, Но с классом необходимо вызвать конструктора. Так, тот код прекрасен.

0
ответ дан Lucas Gabriel Sánchez 24 November 2019 в 08:26
поделиться

В Java синтаксис "текст" создает экземпляр класса java.lang. Строка. Присвоение:

String foo = "text";

простое присвоение, без необходимого конструктора копии.

MyString bar = "text";

недопустимо независимо от того, что Вы делаете, потому что класс MyString не ни один java.lang. Строка или суперкласс java.lang. Строка.

0
ответ дан Darron 24 November 2019 в 08:26
поделиться

CaseInsensitiveString и Строка являются различными объектами. Вы не можете сделать:

CaseInsensitiveString cis = "Polish";

, потому что "польским языком" является Строка, не CaseInsensitiveString. Если бы Строка расширила Строку CaseInsensitiveString тогда, то Вы были бы в порядке, но очевидно это не делает.

И не волнуются о конструкции здесь, Вы не будете делать ненужные объекты. При рассмотрении кода конструктора все, что он делает, хранит ссылку на строку, в которой Вы передали. Ничто дополнительное не создается.

В Строке s = новая Строка ("foobar") случай это делает что-то другое. Вы сначала создаете литеральную строку "foobar", затем создавая копию его путем построения новой строки из него. Нет никакой потребности создать ту копию.

2
ответ дан Herms 24 November 2019 в 08:26
поделиться

В Вашем первом примере Вы создаете Строку, "глупую", и затем передаете его в качестве параметра конструктору копии другой Строки, который делает вторую Строку, которая идентична первому. Так как Строки Java неизменны (что-то, что часто жалит людей, которые привыкли к струнам до), это - бессмысленные траты ресурсов. Необходимо вместо этого использовать второй пример, потому что он пропускает несколько бесполезных шагов.

Однако Строковым литералом не является CaseInsensitiveString, таким образом, там Вы не можете сделать то, что Вы хотите в своем последнем примере. Кроме того, нет никакого способа перегрузиться, оператор кастинга как Вы может в C++, таким образом, нет буквально никакого способа сделать то, что Вы хотите. Необходимо вместо этого передать его в в качестве параметра конструктору класса. Конечно, я, вероятно, просто использовал бы String.toLowerCase () и был бы сделан с ним.

кроме того, Ваш CaseInsensitiveString должен реализовать интерфейс CharSequence, а также вероятно сериализуемые и Сопоставимые интерфейсы. Конечно, если Вы реализуете Сопоставимый, необходимо переопределить, равняется () и хэш-код () также.

3
ответ дан James 24 November 2019 в 08:26
поделиться

- Как я заставляю CaseInsensitiveString вести себя как Строка, таким образом, вышеупомянутый оператор соглашается (с и w/out, расширяющий Строку)? Что о Строке делает его хорошо, чтобы просто быть в состоянии передать его литерал как этот? От моего понимания в праве Java нет никакого "понятия" конструктора копии?

Достаточно было сказано от первой точки. "Польский язык" является строковым литералом и не может быть присвоен классу CaseInsentiviveString.

Теперь о 1124-секундной точке

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

    // Lets test the insensitiveness
    CaseInsensitiveString cis5 = CaseInsensitiveString.valueOf("sOmEtHiNg");
    CaseInsensitiveString cis6 = CaseInsensitiveString.valueOf("SoMeThInG");

    assert cis5 == cis6;
    assert cis5.equals(cis6);

Вот код.

C:\oreyes\samples\java\insensitive>type CaseInsensitiveString.java
import java.util.Map;
import java.util.HashMap;

public final class CaseInsensitiveString  {


    private static final Map<String,CaseInsensitiveString> innerPool 
                                = new HashMap<String,CaseInsensitiveString>();

    private final String s;


    // Effective Java Item 1: Consider providing static factory methods instead of constructors
    public static CaseInsensitiveString valueOf( String s ) {

        if ( s == null ) {
            return null;
        }
        String value = s.toLowerCase();

        if ( !CaseInsensitiveString.innerPool.containsKey( value ) ) {
             CaseInsensitiveString.innerPool.put( value , new CaseInsensitiveString( value ) );
         }

         return CaseInsensitiveString.innerPool.get( value );   
    }

    // Class constructor: This creates a new instance each time it is invoked.
    public CaseInsensitiveString(String s){
        if (s == null) {
            throw new NullPointerException();
         }         
         this.s = s.toLowerCase();
    }

    public boolean equals( Object other ) {
         if ( other instanceof CaseInsensitiveString ) {
              CaseInsensitiveString otherInstance = ( CaseInsensitiveString ) other;
             return this.s.equals( otherInstance.s );
         }

         return false;
    }


    public int hashCode(){
         return this.s.hashCode();
    }

//Тест класс с помощью "утверждать" ключевого слова

    public static void main( String [] args ) {

        // Creating two different objects as in new String("Polish") == new String("Polish") is false
        CaseInsensitiveString cis1 = new CaseInsensitiveString("Polish");
        CaseInsensitiveString cis2 = new CaseInsensitiveString("Polish");

        // references cis1 and cis2 points to differents objects.
        // so the following is true
        assert cis1 !=  cis2;      // Yes they're different
        assert cis1.equals(cis2);  // Yes they're equals thanks to the equals method

        // Now let's try the valueOf idiom
        CaseInsensitiveString cis3 = CaseInsensitiveString.valueOf("Polish");
        CaseInsensitiveString cis4 = CaseInsensitiveString.valueOf("Polish");

        // References cis3 and cis4 points to same  object.
        // so the following is true
        assert cis3 == cis4;      // Yes they point to the same object
        assert cis3.equals(cis4); // and still equals.

        // Lets test the insensitiveness
        CaseInsensitiveString cis5 = CaseInsensitiveString.valueOf("sOmEtHiNg");
        CaseInsensitiveString cis6 = CaseInsensitiveString.valueOf("SoMeThInG");

        assert cis5 == cis6;
        assert cis5.equals(cis6);

        // Futhermore
        CaseInsensitiveString cis7 = CaseInsensitiveString.valueOf("SomethinG");
        CaseInsensitiveString cis8 = CaseInsensitiveString.valueOf("someThing");

        assert cis8 == cis5 && cis7 == cis6;
        assert cis7.equals(cis5) && cis6.equals(cis8);
    }

}

C:\oreyes\samples\java\insensitive>javac CaseInsensitiveString.java


C:\oreyes\samples\java\insensitive>java -ea CaseInsensitiveString

C:\oreyes\samples\java\insensitive>

таким образом, создайте внутренний пул объектов CaseInsensitiveString и возвратите corrensponding экземпляр оттуда.

Этот путь "==" возвраты оператора верный для двух ссылок объектов, представляющих то же значение .

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

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

, класс не завершен, некоторые интересные проблемы возникает, когда мы пытаемся обойти содержание объекта при реализации интерфейса CharSequence, но этот код достаточно хорош, чтобы показать, как тот объект в Книге мог быть применен.

важно заметить, что при помощи объект internalPool, ссылки не выпущены и таким образом не предмет коллекционирования мусора, и это может стать проблемой, если много объектов создается.

Это работает на Строковый класс, потому что это используется интенсивно, и пул составлен "интернированного" объекта только.

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

И наконец это - также причина, почему valueOf (интервал) в классе Целое число ограничен-128 к 127 международным значениям.

4
ответ дан OscarRyz 24 November 2019 в 08:26
поделиться

Вы не можете. Вещи в двойных кавычках в Java особенно распознаны компилятором как Строки, и к сожалению Вы не можете переопределить это (или расшириться java.lang.String - это объявило final).

6
ответ дан Dan Vinton 24 November 2019 в 08:26
поделиться

Строки Java интересны. Похоже, что ответы ответили на некоторые интересные вопросы. Вот мои два цента.

строки неизменны (Вы никогда не можете изменять их)

String x = "x";
x = "Y"; 
  • , первая строка создаст переменную x, который будет содержать строковое значение "x". JVM будет смотреть в своем пуле строковых значений и видеть, существует ли "x", если это делает, это укажет на переменную x на него, если это не существует, это создаст его и затем сделает присвоение
  • , вторая строка будет удалять ссылку на "x" и видеть, существует ли "Y" в пуле строковых значений. Если это действительно будет существовать, это присвоит его, если это не сделает, это создаст его сначала тогда присвоение. Поскольку строковые значения используются или нет, пространство памяти в пуле строковых значений будет исправлено.

сравнения строк зависят от того, что Вы сравниваете

String a1 = new String("A");

String a2 = new String("A");
  • a1, не равняется a2
  • a1, и a2 ссылки на объект
  • , Когда строка явно объявляется, новые экземпляры создаются, и их ссылки не будут тем же.

я думаю, что Вы находитесь на неправильном пути с попыткой использовать нечувствительный к регистру класс. Оставьте строки в покое. То, о чем Вы действительно заботитесь, - то, как Вы отображаете или сравниваете значения. Используйте другой класс, чтобы отформатировать строку или сделать сравнения.

т.е.

TextUtility.compare(string 1, string 2) 
TextUtility.compareIgnoreCase(string 1, string 2)
TextUtility.camelHump(string 1)

, Так как Вы составляете класс, можно заставить сравнивание сделать то, что Вы хотите - сравнивают текстовые значения.

7
ответ дан Xaerxess 24 November 2019 в 08:26
поделиться

String с являются особенными в Java - они неизменны, и строковые константы автоматически превращены в String объекты.

нет никакого пути к Вашему SomeStringClass cis = "value" пример для применения к любому другому классу.

, И при этом Вы не можете расшириться String, потому что это объявляется как final, означая, что никакое разделение на подклассы не позволяется.

12
ответ дан Alnitak 24 November 2019 в 08:26
поделиться

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

, Если Вы пишете

String s = "Polish";
String t = "Polish";

тогда, s и t на самом деле относятся к тому же объекту, и s == t возвратит true, для "==" для чтения объектов "тот же объект" (или может, так или иначе, я "m не уверенный, если это - часть фактической спецификации языка или просто детали реализации так компилятора, возможно, не безопасно полагаться на это).

, Если Вы пишете

String s = new String("Polish");
String t = new String("Polish");

тогда s! =t (потому что Вы явно создали новую строку), хотя s.equals (t) возвратит true (потому что строка добавляет это поведение к, равняется).

вещь Вы хотите записать,

CaseInsensitiveString cis = "Polish";

не может работать, потому что Вы думаете, что цитаты являются своего рода конструктором короткого замыкания для Вашего объекта, когда на самом деле это только работает на простой java.lang. Строки.

30
ответ дан Steve B. 24 November 2019 в 08:26
поделиться

Я полагаю, что основное преимущество использования литеральной формы (т.е., "нечто", а не новая Строка ("нечто")) - то, что все Строковые литералы 'интернируются' VM. Другими словами, это добавляется к пулу, таким образом, что любой другой код, который создает ту же строку, будет использовать объединенную Строку вместо того, чтобы создать новый экземпляр.

Для иллюстрирования следующий код распечатает верный для первой строки, но лжи для второго:

System.out.println("foo" == "foo");
System.out.println(new String("bar") == new String("bar"));
56
ответ дан Leigh 24 November 2019 в 08:26
поделиться

String - это один из специальных классов, в котором вы можете создавать их без новой части Sring

, это то же самое, что

int x = y;

или

char c;

0
ответ дан 24 November 2019 в 08:26
поделиться

То, что в вашем классе есть слово String, не означает, что вы получаете все специальные возможности встроенного класса String.

3
ответ дан 24 November 2019 в 08:26
поделиться
Другие вопросы по тегам:

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