← Назад к вопросам

Является ли строка объектом?

1.0 Junior🔥 181 комментариев
#Soft Skills и карьера

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Является ли строка объектом?

Ответ: Да, строка (String) в Java — это объект, экземпляр класса java.lang.String.

Всё в Java — объект, включая строки. Однако String имеет ряд особенностей, которые делают его уникальным.

Строка как объект

В Java String — это класс с методами и свойствами:

public class StringExample {
    public static void main(String[] args) {
        // Создание строк
        String str1 = "Hello";          // Литерал (создаётся в String Pool)
        String str2 = new String("Hello"); // Явное создание объекта
        String str3 = str1;             // Ссылка на тот же объект
        
        // Проверка, что это объект
        System.out.println(str1 instanceof String);  // true
        System.out.println(str1.getClass());         // class java.lang.String
        System.out.println(str1.getClass().getSuperclass()); // class java.lang.Object
        
        // Методы объекта String
        System.out.println(str1.length());           // 5
        System.out.println(str1.toUpperCase());      // HELLO
        System.out.println(str1.charAt(0));          // H
        System.out.println(str1.substring(1, 3));    // el
    }
}

String наследует Object

// Иерархия наследования
public final class String implements Serializable, Comparable<String>, CharSequence {
    // Внутренние поля
    private final char[] value;  // Массив символов
    private final int hash;      // Кэшированное значение хеша
    
    // Методы из Object
    @Override
    public boolean equals(Object obj) { ... }
    
    @Override
    public int hashCode() { ... }
    
    @Override
    public String toString() { ... }
    
    // Свои методы
    public int length() { ... }
    public char charAt(int index) { ... }
    public String substring(int start) { ... }
    // и сотни других...
}

Особенность: Immutable (неизменяемость)

Одна из ключевых особенностей String — он неизменяем (immutable). После создания строку НЕЛЬЗЯ изменить:

public class StringImmutability {
    public static void main(String[] args) {
        String str = "Hello";
        str.toUpperCase();  // Создаёт НОВЫЙ объект String
        System.out.println(str);  // "Hello" — исходная не изменилась!
        
        // Правильно:
        str = str.toUpperCase();  // Переменная ссылается на новый объект
        System.out.println(str);  // "HELLO"
    }
}

Почему это вызывает новую строку:

str = "Hello"      str ──────→ [String object: "Hello"]

str.toUpperCase()  [String object: "Hello"]
                   [String object: "HELLO"] ← новый объект

str = str.toUpperCase()  str ──────→ [String object: "HELLO"]
                         [String object: "Hello"] ← может быть удалена GC

String Pool (пул строк)

Java имеет специальную память для строк — String Pool, где хранятся строки-литералы для экономии памяти:

public class StringPoolExample {
    public static void main(String[] args) {
        // Литералы создаются в String Pool
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = new String("Hello");  // В heap, не в pool
        
        // Сравнение ссылок
        System.out.println(str1 == str2);    // true! Одна строка в pool
        System.out.println(str1 == str3);    // false! Разные объекты
        
        // Сравнение значений
        System.out.println(str1.equals(str2));   // true
        System.out.println(str1.equals(str3));   // true
        
        // Явное добавление в pool
        String str4 = str3.intern();  // Добавляет в pool и возвращает ссылку
        System.out.println(str1 == str4);  // true! Теперь в pool
    }
}

Визуальное представление:

String Pool (Metaspace)           Heap Memory
┌─────────────────┐               ┌─────────────────┐
│ "Hello" (0x1000)│←───str1───────│ (ссылка)        │
│                 │←───str2       │                 │
└─────────────────┘               │ "Hello" (0x2000)│←str3
                                  │ (new String)    │
                                  └─────────────────┘

Методы String (некоторые)

public class StringMethods {
    public static void main(String[] args) {
        String str = "Hello World";
        
        // Основные методы
        System.out.println(str.length());              // 11
        System.out.println(str.charAt(0));             // H
        System.out.println(str.indexOf("World"));      // 6
        System.out.println(str.substring(0, 5));       // Hello
        System.out.println(str.toUpperCase());         // HELLO WORLD
        System.out.println(str.toLowerCase());         // hello world
        System.out.println(str.contains("World"));     // true
        System.out.println(str.startsWith("Hello"));   // true
        System.out.println(str.endsWith("World"));     // true
        
        // Замена
        System.out.println(str.replace("World", "Java")); // Hello Java
        System.out.println(str.replaceAll("l", "L"));     // HeLLo WorLd
        
        // Разделение и объединение
        String[] parts = str.split(" ");  // ["Hello", "World"]
        String joined = String.join("-", "a", "b", "c");  // a-b-c
        
        // Сравнение
        System.out.println(str.equals("Hello World"));     // true
        System.out.println(str.equalsIgnoreCase("hello world")); // true
        System.out.println(str.compareTo("Hello World"));  // 0
    }
}

Важные методы для интервью

equals() vs ==

public class StringComparison {
    public static void main(String[] args) {
        String a = "Hello";
        String b = "Hello";
        String c = new String("Hello");
        
        // == — сравнивает ССЫЛКИ (адреса в памяти)
        System.out.println(a == b);      // true (одна строка в pool)
        System.out.println(a == c);      // false (разные объекты)
        
        // equals() — сравнивает ЗНАЧЕНИЯ
        System.out.println(a.equals(b)); // true
        System.out.println(a.equals(c)); // true
        
        // ПРАВИЛО: для String используй ВСЕГДА equals()
    }
}

hashCode()

public class StringHashCode {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = new String("Hello");
        
        // hashCode() одинаков для одинаковых значений
        System.out.println(str1.hashCode());  // -1557280266
        System.out.println(str2.hashCode());  // -1557280266 (то же)
        System.out.println(str3.hashCode());  // -1557280266 (то же)
        
        // Использование в HashMap, HashSet
        Set<String> set = new HashSet<>();
        set.add("Hello");
        set.add(str1);
        set.add(str3);
        System.out.println(set.size());  // 1 (все одна строка!)
    }
}

Внутреннее устройство

// Примерная реализация String (упрощённо)
public final class String implements Serializable, Comparable<String> {
    // Основное поле — массив символов (неизменяемый)
    private final char[] value;
    
    // Кэшированное значение хеша
    private int hash;
    
    // Конструкторы
    public String() { ... }
    public String(String original) { ... }
    public String(char[] value) { ... }
    
    // Методы
    public int length() {
        return value.length;
    }
    
    public char charAt(int index) {
        if (index < 0 || index >= value.length) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return value[index];
    }
    
    @Override
    public int hashCode() {
        if (hash == 0 && value.length > 0) {
            hash = computeHash();
        }
        return hash;
    }
    
    @Override
    public boolean equals(Object anObject) {
        if (this == anObject) return true;  // Одна ссылка
        if (anObject instanceof String) {
            String aString = (String) anObject;
            if (this.value.length == aString.value.length) {
                // Сравниваем символы
                return compareTo(aString) == 0;
            }
        }
        return false;
    }
}

StringBuilder для изменяемых строк

Если нужна "изменяемая строка", используй StringBuilder (или StringBuffer для многопоточности):

public class StringBuilderExample {
    public static void main(String[] args) {
        // Неправильно: создаёт много объектов
        String result = "";
        for (int i = 0; i < 1000; i++) {
            result += "item" + i;  // Создаёт новый String каждый раз!
        }
        // 1000 объектов String в памяти
        
        // Правильно: используй StringBuilder
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 1000; i++) {
            sb.append("item").append(i);
        }
        String result2 = sb.toString();  // Один раз создан String
        // Только один объект String в памяти!
    }
}

Вывод

Да, строка в Java — это объект класса String. Ключевые характеристики:

  1. Объект — экземпляр класса java.lang.String, наследует Object
  2. Immutable — не может быть изменена после создания
  3. String Pool — литералы кэшируются для экономии памяти
  4. Методы — сотни методов для работы с текстом
  5. Equals vs == — используй equals() для сравнения значений
  6. StringBuilder — для "изменяемых" строк используй StringBuilder

Понимание этих особенностей критично для написания эффективного и безопасного Java-кода.

Является ли строка объектом? | PrepBro