«1. Введение

В этой статье мы дадим краткое объяснение различий между преобразованием строк и выполнением метода toString(). Мы кратко рассмотрим оба синтаксиса и рассмотрим пример, объясняющий цели использования каждого из них. Наконец, мы рассмотрим, какой из подходов лучше.

2. Приведение типов строк и метод toString()

Начнем с краткого обзора. Использование синтаксиса (String) строго связано с приведением типов в Java. Короче говоря, основная задача использования этого синтаксиса заключается в приведении исходной переменной к строке:

String str = (String) object;

Как мы знаем, каждый класс в Java является расширением, прямо или косвенно, класса Object, который реализует Метод toString(). Мы используем его для получения строкового представления любого объекта:

String str = object.toString();

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

3. (String) vs toString()

Предположим, у нас есть переменная Object, и мы хотим получить строку. Какой синтаксис мы должны использовать?

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

Во-первых, давайте представим простой служебный метод для преобразования объекта в строку:

public static String castToString(Object object) {
    if (object instanceof String) {
        return (String) object;
    }
    return null;
}

Как мы видим, перед преобразованием мы должны проверить, что наша объектная переменная является экземпляром строки. Если мы этого не сделаем, это может привести к сбою и генерации ClassCastException:

@Test(expected = ClassCastException.class)
public void givenIntegerObject_whenCastToObjectAndString_thenCastClassException() {
    Integer input = 1234;

    Object obj = input;
    String str = (String) obj;
}

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

@Test
public void givenNullInteger_whenCastToObjectAndString_thenSameAndNoException() {
    Integer input = null;

    Object obj = input;
    String str = (String) obj;

    assertEquals(obj, str);
    assertEquals(str, input);
    assertSame(input, str);
}

Теперь пришло время реализовать другую служебную функцию, вызывающую toString() для запрошенного объекта:

public static String getStringRepresentation(Object object) {
    if (object != null) {
        return object.toString();
    }
    return null;
}

В этом случае нам не нужно знать тип объекта, и он может быть успешно выполнен на объекте без приведения типов. Нам нужно только добавить простую нулевую проверку. Если мы не добавим эту проверку, мы можем получить NullPointerException при передаче переменной без экземпляра в метод:

@Test(expected = NullPointerException.class)
public void givenNullInteger_whenToString_thenNullPointerException() {
    Integer input = null;

    String str = input.toString();
}

Кроме того, из-за реализации ядра String выполнение метода toString() для переменной String возвращает тот же объект:

@Test
public void givenString_whenToString_thenSame() {
    String str = "baeldung";

    assertEquals("baeldung", str.toString());
    assertSame(str, str.toString());
}

Давайте вернемся к нашему вопросу — какой синтаксис мы должны использовать для нашей объектной переменной? Как мы видели выше, если мы знаем, что наша переменная является экземпляром String, мы должны использовать приведение типов:

@Test
public void givenString_whenCastToObject_thenCastToStringReturnsSame() {
    String input = "baeldung";
    
    Object obj = input;
    
    assertSame(input, StringCastUtils.castToString(obj));
}

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

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

@Test
public void givenIntegerNotNull_whenCastToObject_thenGetToStringReturnsString() {
    Integer input = 1234;

    Object obj = input;

    assertEquals("1234", StringCastUtils.getStringRepresentation(obj));
    assertNotSame("1234", StringCastUtils.getStringRepresentation(obj));
}

4. Заключение

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

Как всегда, полный исходный код статьи доступен на GitHub.