Цель использования StringBuilder, т.е. уменьшение памяти. Это достигнуто?
Нет, совсем нет. Этот код используется StringBuilder
неправильно. (Я думаю, вы неверно процитировали это; наверняка вокруг нет цитат id2
и table
?)
Обратите внимание, что цель (обычно) - уменьшить отток памяти, а не общий объем используемой памяти, чтобы немного облегчить жизнь сборщику мусора.
Будет ли это занимать память, равную использованию String, как показано ниже?
Нет, это вызовет больший отток памяти, чем просто указанное вами прямое соединение. (До тех пор, пока оптимизатор JVM не увидит, что явное указание StringBuilder
в коде не нужно, и оптимизирует его, если сможет.)
Если автор этого кода хочет использовать StringBuilder
(есть аргументы за, но также и против; см. Примечание в конце этого ответа), лучше сделать это правильно (здесь я предполагаю, что на самом деле нет кавычек id2
и table
):
StringBuilder sb = new StringBuilder(some_appropriate_size);
sb.append("select id1, ");
sb.append(id2);
sb.append(" from ");
sb.append(table);
return sb.toString();
Обратите внимание, что я перечислил some_appropriate_size
в StringBuilder
конструкторе, так что он начинается с достаточной емкости для всего содержимого, которое мы собираемся добавить. Размер по умолчанию, используемый, если вы не укажете один, составляет 16 символов , что обычно слишком мало и приводит к StringBuilder
необходимости выполнять перераспределение, чтобы увеличить себя (IIRC, в Sun / Oracle JDK, он удваивается [или больше, если он знает, что ему нужно больше, чтобы удовлетворить конкретный append
] каждый раз, когда ему не хватает места).
Возможно, вы слышали, что для конкатенации строк будет использоваться StringBuilder
скрытый символ, если он скомпилирован с помощью компилятора Sun / Oracle. Это правда, он будет использовать один StringBuilder
для общего выражения. Но он будет использовать конструктор по умолчанию, что означает, что в большинстве случаев ему придется перераспределить. Хотя читать легче. Обратите внимание, что это не относится к серии конкатенаций. Так, например, здесь используется один StringBuilder
:
return "prefix " + variable1 + " middle " + variable2 + " end";
Это примерно означает:
StringBuilder tmp = new StringBuilder();
tmp.append("prefix ");
tmp.append(variable1);
tmp.append(" middle ");
tmp.append(variable2);
tmp.append(" end");
return tmp.toString();
Так что ничего страшного, хотя конструктор по умолчанию и последующее перераспределение (я) не идеальны, скорее всего, он достаточно хорош - и конкатенация намного более читабельна.
Но это только для одного выражения. Для этого StringBuilder
используются несколько s:
String s;
s = "prefix ";
s += variable1;
s += " middle ";
s += variable2;
s += " end";
return s;
В итоге получается что-то вроде этого:
String s;
StringBuilder tmp;
s = "prefix ";
tmp = new StringBuilder();
tmp.append(s);
tmp.append(variable1);
s = tmp.toString();
tmp = new StringBuilder();
tmp.append(s);
tmp.append(" middle ");
s = tmp.toString();
tmp = new StringBuilder();
tmp.append(s);
tmp.append(variable2);
s = tmp.toString();
tmp = new StringBuilder();
tmp.append(s);
tmp.append(" end");
s = tmp.toString();
return s;
... что довольно уродливо.
Однако важно помнить, что во всех случаях, за исключением очень немногих, это не имеет значения, и предпочтение отдается удобочитаемости (что повышает ремонтопригодность), за исключением конкретных проблем с производительностью.
PreparedStatement
или что-то подобное: docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html