Цель использования 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(); // Using default 16 character size
tmp.append("prefix ");
tmp.append(variable1);
tmp.append(" middle ");
tmp.append(variable2);
tmp.append(" end");
return tmp.toString();
Так что все в порядке, хотя конструктор по умолчанию и последующее перераспределение (я) не идеальны, вероятность того, что он достаточно хорош & mdash; и конкатенация является много более читабельным.
Но это только для одного выражения. Для этого используются несколько StringBuilder
с:
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;
... что довольно уродливо.
Важно помнить, однако, что во всех, кроме очень немногих случаях это не имеет значения , и предпочтение отдается удобочитаемости (что повышает удобство обслуживания), если исключить конкретную проблему производительности.