У меня есть коллега, который клянется
//in a singleton "Constants" class
public static final String EMPTY_STRING = "";
в классе констант, доступном во всем проекте. Таким образом, мы можем написать что-то вроде
if (Constants.EMPTY_STRING.equals(otherString)) {
...
}
вместо
if ("".equals(otherString)) {
...
}
Я говорю это
Кто здесь идиот?
К вашему сведению: в .NET есть String.Empty в качестве основного API. Некоторые люди клянутся этим. Я всегда использую "", поскольку считаю его таким же фундаментальным, как 0, и его легче читать - поэтому я против любой попытки маскарада;) В любом случае, я верю, что в C# /. NET было время, когда строки не интернировались, но я Я не уверен. В любом случае, в наши дни это уже не проблема ни для Java, ни для C#.
Похоже на дубликат stackoverflow.com/q/4095501, но с дополнительным условием, что ваш коллега хочет заново изобрести колесо.




Я предпочитаю видеть EMPTY_STRING.
Это делает его английским. "" .equals "читает" иначе, чем EMPTY_STRING.equals.
нет никаких причин для уменьшения этого мода.
Но EMPTY_STRING можно определить произвольно. Я бы почувствовал необходимость поискать его определение, если бы натолкнулся на такое в исходном коде, особенно если это не встроенный язык ;-).
Мне не нравится ни один из вариантов. Почему не if (otherString.length() == 0)
Обновлено: я на самом деле всегда кодирую
if (otherString == null || otherString.length() == 0)
Потому что, если otherString имеет значение null, это вызывает исключение
Теперь должно быть 0. Я озадачен, почему я не увидел ответа Дугласа Белки. Должно быть время.
Также существует статический метод служебной программы Jakarta String для определения того, является ли строка пустой, то есть пустой или пустой.
StringUtils от Apache Common гораздо более полезен в этом отношении. Имеет массу хороших статических методов.
Строковые литералы интернированы по умолчанию, поэтому независимо от того, сколько раз вы ссылаетесь на "" в коде, будет только один пустой объект String. Я не вижу никакой пользы в объявлении EMPTY_STRING. В противном случае вы также можете объявить ONE, TWO, THREE, FOUR и т. д. Для целочисленных литералов.
Конечно, если вы захотите позже изменить значение EMPTY_STRING, удобно разместить его в одном месте;)
Они всегда интернированы или просто так? Гарантировано ли вам, что все пустые строки будут равны всем другим пустым строкам, даже вне границ классов и пакетов?
Вся пустая строка литералы. Вы можете создать другие отдельные объекты String, которые также будут пустыми.
Все литералы и значения «постоянных выражений» интернированы. См. Спецификацию JVM: java.sun.com/docs/books/jvms/second_edition/html/…
Кроме того, если вы когда-нибудь увидите в коде EMPTY_STRING, вам действительно нужно проверить, что это такое. Это могло быть "", "" или даже "пусто". Это добавляет (ненужную) когнитивную нагрузку
Зачем вам глобальная переменная в Java? Джеймс Гослинг действительно пытался избавиться от них; не возвращай их, пожалуйста.
Либо
0 == possiblyEmptyString.length()
или же
possiblyEmptyString.isEmpty() // Java 6 only
столь же ясны.
кроме случая, когда возможно, что пустая строка пуста, тогда вы получите NPE
Я думаю, что в определенных сценариях также имеет смысл обрезать значение String при проверке длины, что-то вроде этого: 0 == возможноEmptyString.trim (). Length () Я думаю, что в некоторых сценариях это имеет смысл, потому что если для по любой причине ваша переменная possibleEmptyString имеет это значение "", lenght вернет 3. Конечно, я рассматриваю возможность использования Java 1.5, потому что, как вы заявили, Java 6 имеет метод isEmtpy ().
По иронии судьбы весь смысл констант в том, чтобы сделать их легко изменяемыми. Поэтому, если ваш коллега не планирует переопределить EMPTY_STRING как нечто иное, чем пустая строка - что было бы действительно глупо, - приведение подлинной фиксированной конструкции, такой как "", к константе - это плохо.
Как говорит Дэн Дайер, это похоже на определение константы ONE равной 1: это совершенно бессмысленно и было бы совершенно запутанным - потенциально рискованным - если бы кто-то переопределил его.
Тот же аргумент время от времени возникает в .NET (где уже есть статическое поле string.Empty только для чтения). Это дело вкуса, но лично я нахожу "" менее навязчивым.
Если, конечно, вы случайно не просканируете просеянное пространство, которое вы поместили туда по ошибке.
Хм, правила правильные, но их понимают в другом смысле! Давайте посмотрим на причину, сначала все ссылки на объекты в java проверяются с помощью equals (). Раньше на некоторых языках это делалось с помощью оператора '==', если кто-то случайно использовал '=' вместо '==', катастрофа. Теперь вопрос о магических числах / константах, для компьютера все константы / числа похожи. Вместо int ONE = 1, конечно, можно использовать 1, но будет ли это верно для double PI = 3.141 ...? Что произойдет, если позже кто-то попытается изменить точность.
Если бы мы составили контрольный список, какое правило соответствовало бы общему руководству, не так ли? Все, что я хочу сказать, это то, что правила призваны помогать, мы определенно можем изменить правила, только если знаем их очень хорошо. Здравый смысл преобладает. Как предложил мой друг, программные константы, такие как 0/1, которые обозначают условия выхода, могут быть жестко закодированы, и, следовательно, принцип магического числа не применяется. Но для тех, кто участвует в логических проверках / правилах, лучше сохранить их как настраиваемые константы.
Для подобных ситуаций мы просто делаем следующее:
public class StaticUtils
{
public static boolean empty(CharSequence cs)
{
return cs == null || cs.length() == 0;
}
public static boolean has(CharSequence cs)
{
return !empty(cs);
}
}
Тогда просто import static StaticUtils.*
Строка null - это не то же самое, что пустая строка.
Я с твоим коллегой. Хотя в пустой строке сложно ошибиться, вы можете случайно вставить в нее пробел, и это может быть трудно заметить при сканировании кода. Более того, это хорошая практика - делать это со всеми вашими строковыми константами, которые используются более чем в одном месте, хотя я предпочитаю делать это на уровне класса, а не как глобальные константы.
FWIW, C# имеет строку статического свойства. Пусто только для этой цели, и я считаю, что это значительно улучшает читаемость кода.
Если вы не программируете моноширинный шрифт, вы делаете это неправильно. Если да, то есть очевидная разница между "" и "".
Однако при быстром сканировании нет такой очевидной разницы между "" и "'".
Один случай, когда имеет смысл иметь константу со значением пустой строки, - это когда имя фиксирует семантику значения. Например:
if (Constants.FORM_FIELD_NOT_SET.equals(form.getField("foobar"))) {
...
}
Это делает код более самодокументированным (помимо аргумента о том, что лучший дизайн - это добавить метод, проверяющий, установлено ли поле в самой форме).
Ну, я тоже мог догадаться, но я сделал быструю проверку ... Почти как жульничество ...
Произвольная строка проверяется различными методами. (несколько итераций)
Результаты показывают, что isEmpty () быстрее и более читабельна; Если isEmpty () недоступен, хорошей альтернативой является length ().
Использование константы, вероятно, не стоит.
"".equals(someString()) :24735 ms
t != null && t.equals("") :23363 ms
t != null && t.equals(EMPTY) :22561 ms
EMPTY.equals(someString()) :22159 ms
t != null && t.length() == 0 :18388 ms
t != null && t.isEmpty() :18375 ms
someString().length() == 0 :18171 ms
В этом сценарии;
"IAmNotHardCoded".equals(someString())
Я бы предложил определять константу в любом месте, поскольку глобальный класс для всех констант действительно отстой. Если подходящего места нет, вероятно, вы делаете что-то еще не так ...
Customer.FIELD_SHOE_SIZE //"SHOE_SIZE"
Может считаться подходящим местом, где как;
CommonConstants.I__AM__A__LAZY__PROGRAMMER // true
не является.
Для BigIntegers и подобных вещей я обычно определяю конечную статику локально; нравиться:
private final static BigDecimal ZERO = new BigDecimal(0);
private final static BigDecimal B100 = new BigDecimal("100.00");
Меня это беспокоит, и было бы неплохо добавить немного сахара для BigInts и BigDecimals ...
Хе-хе, забавная штука: После компиляции вы не увидите разницы (в байтовом коде) между "static final" и строковым литералом, поскольку Java-компилятор всегда встраивает "static final String" в целевой класс. Просто измените свою пустую строку на что-нибудь узнаваемое (например, LGPL-текст) и посмотрите на получившийся * .class файл кода, который ссылается на эту константу. Вы найдете свой текст скопированным в этот файл класса.
Что касается вопроса, я обычно рекомендую использовать служебную функцию, когда вы действительно проверяете «отсутствие полезного значения», а не, в частности, пустую строку. В общем, я обычно использую:
import org.apache.commons.lang.StringUtils;
// Check if a String is whitespace, empty ("") or null.
StringUtils.isBlank(mystr);
// Check if a String is empty ("") or null.
StringUtils.isEmpty(mystr);
Идея состоит в том, что два вышеупомянутых:
Почему предпочтительнее использовать String.Empty в C# и, следовательно, общедоступную константу на других языках, заключается в том, что константы статичны, поэтому занимают только один экземпляр в памяти.
Каждый раз, когда вы делаете что-то вроде этого: -
stringVariable = "";
вы создаете новый экземпляр нулевой строки и указываете на него с помощью stringVariable.
Таким образом, каждый раз, когда вы присваиваете "" переменной (указателю), эта "" нулевая строка является новым экземпляром строки до тех пор, пока не перестанет быть присвоенным ей указателем.
инициализация строк путем указания их всех на одну и ту же константу означает, что когда-либо создается только одна "", и каждая инициализированная переменная указывает на одну и ту же пустую строку.
Это может показаться тривиальным, но создание и уничтожение строк требует гораздо больших ресурсов, чем создание указателей (переменных) и их указание на существующую строку.
Поскольку инициализация строки является обычным явлением, рекомендуется: -
const String EMPTY_STRING = "";
String variable1 = EMPTY_STRING;
String variable2 = EMPTY_STRING;
String variable3 = EMPTY_STRING;
String variable4 = EMPTY_STRING;
String variable5 = EMPTY_STRING;
Вы создали 5 указателей на строку, но только 1 строку
скорее, чем: -
String variable1 = "";
String variable2 = "";
String variable3 = "";
String variable4 = "";
String variable5 = "";
Вы создали 5 указателей на строки и 5 отдельных нулевых строк.
В этом случае это не является серьезной проблемой, но в тысячах строк кода в десятках классов это ненужная трата памяти и использование процессора, создание еще одной переменной с нулевой строкой, когда все они могут указывать на одну и ту же, что делает приложения намного более эффективными. .
Конечно, компиляторы должны быть достаточно умными, чтобы определять несколько статических строк и повторно использовать дубликаты, но зачем предполагать?
Кроме того, он менее подвержен ошибкам, так как оба элемента компилируются, но вы можете пропустить случайно добавленное пространство, что может привести к ложным ошибкам времени выполнения, например условной логике, такой как: -
myvariable = " ";
While (myVariable == ""){
...
}
Код внутри блока while недоступен, поскольку myVariable не удовлетворяет условию на первой итерации. Ошибка инициализации с "" вместо "" легко пропустить, тогда как: -
myvariable = EMPTY_STRING;
While (myVariable == EMPTY_STRING){
...
}
... с меньшей вероятностью вызовет ошибки во время выполнения, особенно потому, что неправильное написание EMPTY_STRING приведет к ошибке компиляции вместо того, чтобы перехватывать ошибку во время выполнения.
Самым чистым решением было бы создать статический класс, содержащий элементы всех видов строковых констант, которые вам нужны, если вам потребуется нечто большее, чем просто пустая строка.
public static class StringConstants{
public static String Empty = "";
public static String EMail = "mailto:%s";
public static String http = "http://%s";
public static String https = "https://%s";
public static String LogEntry = "TimeStamp:%tYmdHMSL | LogLevel:%s| Type:%s | Message: '%s'";
}
String myVariable = StringConstants.Empty;
Вы даже можете расширить собственный объект String, в зависимости от вашего языка.
Но интернирование строк… «но в тысячах строк кода в десятках классов это ненужная трата памяти и использование процессора, создание еще одной переменной с нулевой строкой» - вероятно, меньше циклов компилятора используется для интернирования пустой строки в компиляторе Java, чем для расширить константу. Но я не проверял: а вы?
Вопрос не в C#. И: «Он сказал указатель!». ;)
Дэвид Арно заявляет: -
Ironically the whole point of constants is to make them easily changeable
Это просто неправда. Вся суть констант заключается в повторном использовании одного и того же значения для большей читабельности.
Очень редко значения констант меняются (отсюда и название). Чаще значения конфигурации изменяются, но где-то сохраняются как данные (например, файл конфигурации или запись в реестре).
С самого начала программирования константы использовались, чтобы превратить такие вещи, как загадочные шестнадцатеричные значения, такие как 0xff6d8da412, в нечто удобочитаемое без намерения Когда-либо изменять значения.
const int MODE_READ = 0x000000FF;
const int MODE_EXECUTE = 0x00FF0000;
const int MODE_WRITE = 0x0000FF00;
const int MODE_READ_WRITE = 0x0000FFFF;
«Весь смысл констант заключается в повторном использовании одного и того же значения для большей читабельности». Кроме того, они помогают избежать ошибок, связанных с опечатками, поскольку константы проверяются компилятором, а буквальные значения - нет.
Если вы все время хотите хранить «пустые» строки в столбце строки, допускающей значение NULL, в oracle, вам придется изменить определение EMPTY_STRING на что-то другое, кроме «»! (Я вспоминаю из прошлого раза, когда меня заставляли использовать Oracle, что он не знает разницы между пустой строкой и пустой строкой).
Однако это должно быть сделано на вашем уровне доступа к данным, чтобы остальная часть приложения не знала об этом, и / или отсортировать вашу модель данных, чтобы вам не нужно было хранить пустую строку И пустые строки в одном столбце.
Или просто укажите его как string.IsNullOrEmpty (otherString)
Это вопрос Java, а не C#
Вы имеете в виду otherString.equals("") или предлагаете использовать такую библиотеку, как Guava или Apache Commons?
Пожалуйста, добавьте какое-нибудь пояснение - на этот вопрос уже есть много ответов - чем ваш ответ отличается, почему это лучшее решение?
сотрудник? Как орочь корову? знак равно