34

I have a co-worker that swears by

//in a singleton "Constants" class
public static final String EMPTY_STRING = "";

in a constants class available throughout the project. That way, we can write something like

if (Constants.EMPTY_STRING.equals(otherString)) {
    ...
}

instead of

if ("".equals(otherString)) {
    ...
}

I say it's

  1. not worth it--it doesn't save any space in the heap/stack/string pool,
  2. ugly
  3. abuse of a constants class.

Who is the idiot here?

Meneer Venus
  • 1,039
  • 2
  • 12
  • 28
jacobko
  • 8,740
  • 7
  • 32
  • 36
  • 44
    a cow orker? How does one ork cows? =) – Erik Forbes Oct 18 '08 at 03:44
  • 3
    FYI: In .NET there is a `String.Empty` as core API. Some people swear by it. I always use `""` as I find it as fundamental as 0 and is easier to read -- thus I am opposed to any masquerade attempt ;) Anyway, I believe in C#/.NET there was a time when strings were not interned, but I am not sure. In any case, it is no longer a concern in either Java or C# these days. –  Dec 05 '10 at 09:40
  • Seems like a duplicate of https://stackoverflow.com/q/4095501, but with the extra condition that your coworker wants to re-invent a wheel. – Dawood ibn Kareem May 02 '18 at 23:09

18 Answers18

74

String literals are interned by default, so no matter how many times you refer to "" in code, there will only be one empty String object. I don't see any benefit in declaring EMPTY_STRING. Otherwise, you might as well declare ONE, TWO, THREE, FOUR, etc. for integer literals.

Of course, if you want to change the value of EMPTY_STRING later, it's handy to have it in one place ;)

Dan Dyer
  • 53,737
  • 19
  • 129
  • 165
  • 2
    Are they *always* interned, or just normally so? Are you guaranteed that all empty strings will equal all other empty strings, even across class and package boundaries? – Paul Tomblin Oct 17 '08 at 22:11
  • 2
    All empty String *literals*. You can create other distinct String objects that are also empty. – Dan Dyer Oct 17 '08 at 22:12
  • 7
    All literals and values of "constant expressions" are interned. See JVM spec: http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#20359 – James Schek Oct 18 '08 at 00:23
  • Besides, if you ever see EMPTY_STRING in code, you actually have to check what it is. It could be "", " " or even "empty". This adds (unnecessary) cognitive load – Entreco Sep 11 '20 at 07:34
15

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.

Douglas Squirrel
  • 2,304
  • 2
  • 19
  • 23
  • 11
    except if possiblyEmptyString is null, then you get an NPE – tuler Nov 26 '09 at 19:49
  • I think it would also makes sense, in certain scenarios, to trim the String value when checking lenght, something like this: 0 == possiblyEmptyString.trim().length() I think it does makes sense in some scenarios cause if, for any reason, your possiblyEmptyString variable has this value " ", lenght would return 3. Off course I'm considering using Java 1.5, cause as you stated, Java 6 has isEmtpy() method. – Fernando Moyano Feb 25 '12 at 14:43
7

I much prefer seeing EMPTY_STRING.

It makes it english. "".equals 'reads' differently than EMPTY_STRING.equals.

shelfoo
  • 1,569
  • 13
  • 15
  • 6
    there is no reason for this to be modded down. – Dustin Getz Oct 17 '08 at 22:38
  • 2
    But `EMPTY_STRING` may be defined arbitrarily. I would feel the need to look up its definition if I came across such a thing in source code, especially when it’s not a language built-in ;-). – binki May 20 '14 at 13:13
7

Ironically the whole point of constants is to make them easily changeable. So unless your co-worker plans to redefine EMPTY_STRING to be something other than an empty string - which would be a really stupid thing to do - casting a genuine fixed construct such as "" to a constant is a bad thing.

As Dan Dyer says, its like defining the constant ONE to be 1: it is completely pointless and would be utterly confusing - potentially risky - if someone redefined it.

David Arno
  • 42,717
  • 16
  • 86
  • 131
6

Well, I could guess too, but I did a quick test... Almost like cheating...

An arbitrary string is checked using various methods. (several iterations)

The results suggests that isEmpty() is both faster and indeed more readable; If isEmpty() is not available, length() is a good alternative.

Using a constant is probably not worth it.

"".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

In this scenario;

"IAmNotHardCoded".equals(someString())

I would suggest defining a constant in a r e l e v a n t place, since a global class for all constants really sucks. If there is no relevant place, you are probably doing something else wrong...

Customer.FIELD_SHOE_SIZE //"SHOE_SIZE"

Might be considered a relevant place where as;

CommonConstants.I__AM__A__LAZY__PROGRAMMER // true

is not.

For BigIntegers and similar thing, I tend to end up defining a final static locally; like:

private final static BigDecimal ZERO = new BigDecimal(0);
private final static BigDecimal B100 = new BigDecimal("100.00");

Thats bugs me and wouldn't it be nice with some sugar for BigInts and BigDecimals...

5

I'm with your coworker. While the empty string is hard to mistype, you can accidentally put a space in there and it may be difficult to notice when scanning the code. More to the point it is a good practice to do this with all of your string constants that get used in more than one place -- although, I tend to do this at the class level rather than as global constants.

FWIW, C# has a static property string.Empty for just this purpose and I find that it improves the readability of the code immensely.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
4

As a tangent to the question, I generally recommend using a utility function when what you're really checking for is "no useful value" rather than, specifically, the empty string. In general, I tend to use:

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); 

The concept being that the above two:

  • Check the various other cases, including being null safe, and (more importantly)
  • Conveys what you are trying to test, rather than how to test it.
RHSeeger
  • 16,034
  • 7
  • 51
  • 41
4

David Arno states: -

Ironically the whole point of constants is to make them easily changeable

This is simply not true. The whole point of constants is reuse of the same value and for greater readability.

It is very rare that constant values are changed (hence the name). It is more often that configuration values are changed, but persisted as data somewhere (like a config file or registry entry)

Since early programming, constants have been used to turn things like cryptic hex values such as 0xff6d8da412 into something humanly readable without ever intending to change the values.

const int MODE_READ       = 0x000000FF;
const int MODE_EXECUTE    = 0x00FF0000;
const int MODE_WRITE      = 0x0000FF00;
const int MODE_READ_WRITE = 0x0000FFFF;
Antony Booth
  • 248
  • 4
  • 7
  • 2
    "The whole point of constants is reuse of the same value and for greater readability." Also, they help avoid typo-related bugs since constants are checked by the compiler, whereas literal values are not. – Greg Brown Oct 24 '12 at 12:54
3

I don't like either choice. Why not if (otherString.length() == 0)

Edit: I actually always code

if (otherString == null || otherString.length() == 0)
David G
  • 6,249
  • 4
  • 33
  • 31
2
  1. yes--it offers no benefit.
  2. depends on what you're used to, I'm sure.
  3. No, it's just a constant--not an abuse.
Bill K
  • 62,186
  • 18
  • 105
  • 157
2

The same argument comes up in .NET from time to time (where there's already a readonly static field string.Empty). It's a matter of taste - but personally I find "" less obtrusive.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
2

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).

ddimitrov
  • 3,293
  • 3
  • 31
  • 46
2

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.

1

We just do the following for situations like this:

public class StaticUtils
{
    public static boolean empty(CharSequence cs)
    {
        return cs == null || cs.length() == 0;
    }

    public static boolean has(CharSequence cs)
    {
        return !empty(cs);
    }
}

Then just import static StaticUtils.*

Stephan
  • 41,764
  • 65
  • 238
  • 329
John Nilsson
  • 17,001
  • 8
  • 32
  • 42
0

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.

questzen
  • 3,260
  • 18
  • 21
0

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.

Antony Booth
  • 248
  • 4
  • 7
  • But string interning… “but in thousands of lines of code in dozens of classes, it is unnecessary memory waste and processor use, creating another null string variable”—probably less compiler cycles are used to intern the empty string in the Java compiler than to expand a constant. But I haven’t checked: have you? – binki May 20 '14 at 13:19
  • The question isn't about C#. And: "[He said _pointer_!](https://www.youtube.com/watch?v=MIaORknS1Dk)". ;) – Gerold Broser Jul 03 '16 at 12:23
0

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.

Ian Ringrose
  • 51,220
  • 55
  • 213
  • 317
0

Or simply just have it as string.IsNullOrEmpty(otherString)