Мета використання StringBuilder, тобто зменшення пам'яті. Чи досягнуто це?
Ні, зовсім ні. Цей код використовується StringBuilderнеправильно. (Мені здається, ви це неправильно вказали; звичайно там немає цитат навколо id2таtable ?)
Зверніть увагу, що метою (як правило) є зменшення відтоку пам’яті, а не загальної використаної пам’яті, щоб полегшити життя збирача сміття.
Чи буде пам'ять рівною використанню рядка, як показано нижче?
Ні, це спричинить більший обсяг пам’яті, ніж просто прямий конкат, який ви цитували. (Поки / якщо 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