I have a co-worker that swears by
//in a singleton \"Constants\" class
public static final String EMPTY_STRING = \"\";
in a constants class
Hehe, funny thing is: Once it compiles, you wont see a difference (in the byte-code) between the "static final" thing and the string literal, as the Java-compiler always inlines "static final String" into the target class. Just change your empty string into something recognizable (like the LGPL-text) and look at the resulting *.class file of code that refernces that constant. You will find your text copied into that class-file.
One case where it does make sense to have a constant with value of empty string is when you the name captures the semantics of the value. For example:
if (Constants.FORM_FIELD_NOT_SET.equals(form.getField("foobar"))) {
...
}
This makes the code more self documenting (apart from the argument that a better design is to add the method checking whether a field is set to the form itself).
Hmm, the rules are right but are being taken in a different sense! Lets look at the cause, firstly all object references in java are checked by equals(). Earlier on, in some languages it was done using '==' operator, if by accident someone used '=' for '==', a catastrophe. Now the question of magic numbers/constants, for a computer all constants/numbers are similar. Instead of 'int ONE=1' one can surely use 1, but will that hold true for double PI = 3.141...? What happens if someone tries to change the precision sometime later.
If we were to come up with a check list, what would the rule be address the general guideline isn't it? All I mean to say is that rules are supposed to aid, we can surely bend the rules only when we know them very well. Common sense prevails. As suggested by a friend of mine, program constants like 0/1 which denote exit conditions can be hard coded and hence magic number principle doesn't apply. But for those which participate in logical checks/rules, better keep them as configurable constants.
Why on earth would you want a global variable in Java? James Gosling really tried to get rid of them; don't bring them back, please.
Either
0 == possiblyEmptyString.length()
or
possiblyEmptyString.isEmpty() // Java 6 only
are just as clear.
Why it is preferable to use String.Empty in C# and therefore a public constant in other languages, is that constants are static, therefore only take up one instance in memory.
Every time you do something like this: -
stringVariable = "";
you are creating a new instance of a null string, and pointing to it with stringVariable.
So every time you make an assignment of "" to a variable (pointer), that "" null string is a new string instance until it no longer has any pointer assignments to it.
initializing strings by pointing them all to the same constant, means only one "" is ever created and every initialized variable points to the same null string.
It may sound trivial, but creating and destroying strings is much more resource intensive than creating pointers (variables) and pointing them to an existing string.
As string initialization is common, it is good practice to do: -
const String EMPTY_STRING = "";
String variable1 = EMPTY_STRING;
String variable2 = EMPTY_STRING;
String variable3 = EMPTY_STRING;
String variable4 = EMPTY_STRING;
String variable5 = EMPTY_STRING;
You have created 5 string pointers but only 1 string
rather than: -
String variable1 = "";
String variable2 = "";
String variable3 = "";
String variable4 = "";
String variable5 = "";
You have created 5 string pointers and 5 separate null strings.
Not a major issue in this case, but in thousands of lines of code in dozens of classes, it is unnecessary memory waste and processor use, creating another null string variable, when they can all point to the same one, making applications much more efficient.
Of course, compilers should be clever enough to determine several static strings and reuse duplicates, but why assume?
Also, it's less prone to introducing errors as "" and " " will both compile, yet you may miss the space you accidentally added which could produce spurious run time errors, for example conditional logic such as: -
myvariable = " ";
While (myVariable == ""){
...
}
Code inside the while block is unreachable because myVariable will not satisfy the condition on the first iteration. The error of initializing with " " instead of "" is easy to miss, whereas: -
myvariable = EMPTY_STRING;
While (myVariable == EMPTY_STRING){
...
}
... is less likely to cause runtime errors, especially as misspelling EMPTY_STRING would generate a compile error instead of having to catch the error at run time.
The cleanest solution, would be to create a static class that contains members of all kinds of string constants you need, should you require more than just an 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;
You may even be able to extend the native String object, depending on your language.
If you every wish to store "empty" strings in a nullable string column in oracle, you will have to change the definition of EMPTY_STRING to be something other than ""! (I recall from the last time I was forced to use Oracle that it does not know the difference between an empty string and a null string).
However this should be done in your data access layer so the rest of the app does not know about it, and/or sort out your data model so you don’t need to store empty string AND null strings in the same column.