329

I understand that every time I type the string literal "", the same String object is referenced in the string pool.

But why doesn't the String API include a public static final String Empty = "";, so I could use references to String.Empty?

It would save on compile time, at the very least, since the compiler would know to reference the existing String, and not have to check if it had already been created for reuse, right? And personally I think a proliferation of string literals, especially tiny ones, in many cases is a "code smell".

So was there a Grand Design Reason behind no String.Empty, or did the language creators simply not share my views?

12
  • 6
    Aidanc: I think he means situations where you do stuff like outputBlah = "", and he probably prefers something == String.Empty over something.Length > 0 as well (you skip a null check.) Commented Aug 10, 2010 at 15:31
  • 5
    @Aidanc - He was looking for an "empty member" like Collections.EMPTY_SET, not a function to check for string "emptiness". Commented Aug 10, 2010 at 15:31
  • 3
    @Aidanc: What inspired this is actually 'TextBox.setText("");'. Commented Aug 10, 2010 at 15:34
  • 14
    String.isEmpty() does not return an empty string. Commented Aug 10, 2010 at 18:57
  • 6
    It may have little or no advantage in the actual code, but from a readability standpoint, it has value. (As a c# dev transitioning to java, I miss it) As someone else stated, "" has the potential for error, because it isn't clear if empty was intended or the code is incomplete. Also, it's easy to miss the difference between "" " " and '' when reading the code. I think it has value from the point of avoiding string literals in code, and explicitly stating that it was intentional to set the variable as empty. Commented Feb 7, 2013 at 21:46

12 Answers 12

218

String.EMPTY is 12 characters, and "" is two, and they would both be referencing exactly the same instance in memory at runtime. I'm not entirely sure why String.EMPTY would save on compile time, in fact I think it would be the latter.

Especially considering Strings are immutable, it's not like you can first get an empty String, and perform some operations on it - best to use a StringBuilder (or StringBuffer if you want to be thread-safe) and turn that into a String.

Update
From your comment to the question:

What inspired this is actually TextBox.setText("");

I believe it would be totally legitimate to provide a constant in your appropriate class:

private static final String EMPTY_STRING = "";

And then reference it as in your code as

TextBox.setText(EMPTY_STRING);

As this way at least you are explicit that you want an empty String, rather than you forgot to fill in the String in your IDE or something similar.

Sign up to request clarification or add additional context in comments.

29 Comments

I'll still +1 you, but I feel dirty because you mentioned StringBuilder without talking about how nine times out of ten it's totally inappropriate to use StringBuilder rather than concatenation.
I tend to prefer string.empty, mostly because it is more explicit. Also, there are rate situations where it can be harder to visually differentiate "" and things like "'". In the end as others have noted it is just one of those meaningless style things that give us fodder to argue over when we are bored with real work. =)
@Randolpho When using string concatenation your are actually using a StringBuilder under the hood.
-1 - String.EMPTY must be a final static reference, so that in running time it will be just a unique reference. If you use "" you are duplicating a reference everytime you use it. I think this is the background of the original question...
I'm with @hfrmobile - I haven't tested this, but with regards to this being more efficient due to the number of characters, I disagree. String.Empty is a static variable shared across all instances, will "" always instantiates a new empty string every time. String.Empty would be more efficient.
|
217

Use org.apache.commons.lang.StringUtils.EMPTY

8 Comments

Looks a lot nicer and easier to read than an empty "". I hope it not just me.
@LakatosGyula - I think it might be (just you). Proficient Java programmers have no problems reading "" ... and most would probably object loudly about use of EMPTY except in specific situations where EMPTY has a domain specific meaning. (And in such cases, there is probably a more appropriate name.)
@LakatosGyula It's not just you. I went from Java to .NET development, and String.Empty was a feature I was pleased to find in the framework. I like the explicit nature of it over an empty set of quotes.
@StephenC When I see an empty "" the first thing jumps in my mind that it's a bug, someone not finished the function etc. With String.EMPTY I know exactly that the developer intended to return an empty string.
Also helpful for all those times when the linter says "use a named constant instead of blah blah blah". Every programmer knows "" is not magic, but not having to explain it to the customer is better.
|
33

If you want to compare with empty string without worrying about null values you can do the following.

if ("".equals(text))

Ultimately you should do what what you believe is clearest. Most programmers assume "" means empty string, not a string someone forgot to put anything into.

If you think there is a performance advantage, you should test it. If you don't think its worth testing for yourself, its a good indication it really isn't worth it.

It sounds like to you try to solve a problem which was solved when the language was designed more than 15 years ago.

3 Comments

I am quite late to the party but, since Java strings are immutable, I believe that all empty strings within a JVM are just different references to the same String object. So simply the following is also correct: if ("" == text)
@AjoyBhatia The problem is that you can create new empty strings. if ("" == new String()) is false. A better test if(text.isEmpty())
@AjoyBhatia - Only if the strings are interned. stackoverflow.com/questions/10578984/what-is-string-interning
15

Don't just say "memory pool of strings is reused in the literal form, case closed". What compilers do under the hood is not the point here. The question is reasonable, specially given the number of up-votes it received.

It's about the symmetry, without it APIs are harder to use for humans. Early Java SDKs notoriously ignored the rule and now it's kind of too late. Here are a few examples on top of my head, feel free to chip in your "favorite" example:

  • BigDecimal.ZERO, but no AbstractCollection.EMPTY, String.EMPTY
  • Array.length but List.size()
  • List.add(), Set.add() but Map.put(), ByteBuffer.put() and let's not forget StringBuilder.append(), Stack.push()

3 Comments

Even if you named the List parameter length() you still need the parenthesis since it's a method. Array.length is a public final variable, which only works because Arrays are immutable. So you'd still have Array.length and List.length(). I would argue that is more confusing and prone to error. As for .append() and .push(), while they do perform similar tasks I think they appropriately named. Appending the String is exactly what you're doing, but you don't "append" a Stack, you push and pop values. And StringBuilder.push() would imply StringBuilder.pop(), which isn't possible.
Coming from templates/generics, consistent interfaces help with algorithms too. If an algorithm needs a length of a collection, length(T) or T.length() is all we care for. Similarly, adding to the end of a stack, list or a string could be done by a universal add() or append(). You mentioned that the array in Java is immutable/builtin type with an exposed length property. That's fine, it doesn't mean the compiler cannot handle or generate code for length(T) or T.length(). Kotlin generates a number of intrinsic methods for various cases.
But a consistently named length() method only lets us check length. How useful is that? If your goal is to abstract Lists and Arrays to make either usable in some way via an interface, you also need a consistent way to read or write data. So now you need to generate get(), set(), and add() methods. Essentially, you are creating a less functional List view of the Array. Since Arrays.asList() is available, easy to use, and lightweight, why reinvent the wheel? Arrays, Lists, StringBuilders, and Stacks all have a specific purpose. Seems better to design your interface to use the best fit.
10

Seems like this is the obvious answer:

String empty = org.apache.commons.lang.StringUtils.EMPTY;

Awesome because "empty initialization" code no longer has a "magic string" and uses a constant.

Comments

9

Apache StringUtils addresses this problem too.

Failings of the other options:

  • isEmpty() - not null safe. If the string is null, throws an NPE
  • length() == 0 - again not null safe. Also does not take into account whitespace strings.
  • Comparison to EMPTY constant - May not be null safe. Whitespace problem

Granted StringUtils is another library to drag around, but it works very well and saves loads of time and hassle checking for nulls or gracefully handling NPEs.

1 Comment

so... it seems the only safe option is the awful Yoda condition: "".equals(s)?
8

If you really want a String.EMPTY constant, you can create an utility static final class named "Constants" (for example) in your project. This class will maintain your constants, including the empty String...

In the same idea, you can create ZERO, ONE int constants... that don't exist in the Integer class, but like I commented, it would be a pain to write and to read :

for(int i=Constants.ZERO; ...) {
    if(myArray.length > Constants.ONE) {
        System.out.println("More than one element");
    }
}

Etc.

1 Comment

This is generally considered bad practice en.wikipedia.org/wiki/Constant_interface
5

All those "" literals are the same object. Why make all that extra complexity? It's just longer to type and less clear (the cost to the compiler is minimal). Since Java's strings are immutable objects, there's never any need at all to distinguish between them except possibly as an efficiency thing, but with the empty string literal that's not a big deal.

If you really want an EmptyString constant, make it yourself. But all it will do is encourage even more verbose code; there will never be any benefit to doing so.

5 Comments

x = String.Empty conveys intent better than x = "". The latter could be an accidental omission. To say that there is never any benefit is incorrect.
@Jeffrey: I don't think I particularly agree. It's one of these things where there's no hard and fast rule I suppose.
Yes, it's important to point out that the java compiler checks whether string literals already exist before creating a new instance in the string pool.
@Jeffrey - knowing that this is a very old and subjective discussion. x = String.Empty conveys intent, true. But suppose the language provides a constant String.Empty, when you encounter x = "" you still know exactly as much about the intent as if there wasn't such a constant. You would need guarantee that all places in the worlds Java code where an empty string was intendet don't use "" in order to get the information gain you mention. Ironically, C# does use a constant and encourages its use, so as I said, I know it is a very opinonated discussion.
@chiccodoro - Yes, that’s true. That’s why the empty string literal "" should be illegal, to rule out accidents. I’m kidding!
4

To add on to what Noel M stated, you can look at this question, and this answer shows that the constant is reused.

http://forums.java.net/jive/message.jspa?messageID=17122

String constant are always "interned" so there is not really a need for such constant.

String s=""; String t=""; boolean b=s==t; // true

1 Comment

the link is dead.
3

I understand that every time I type the String literal "", the same String object is referenced in the String pool.
There's no such guarantee made. And you can't rely on it in your application, it's completely up to jvm to decide.

or did the language creators simply not share my views?
Yep. To me, it seems very low priority thing.

5 Comments

There's no such guarantee made ...Well, the JLS does state that should be the case.
@Tim Not unless you make 'intern' call. It's easy to construct two equal big strings programmatically and check.
@Tim For example, repeat a += "a"; 100 times, do same with b and check.
You're right, but what you've described isn't a string literal, nor an expression whose result can be guaranteed at compile time (such as String username = "Bob" + " " + "Smith";). Strings created programmatically have no guarantees of being interned, unless you explicitly call intern() as you've stated. The OP's scenario describes using the blank string literal "" throughout the code though, which is a case where automatic interning would occur.
@Tim String a = ""; for(int i = 0; i < 100; i++) {a += "a";} String b = ""; for(int i = 0; i < 100; i++) {b += "b";} a.intern(); b.intern(); Now the a and b point to the same memory location in PermGen. See this article
3

Late answer, but I think it adds something new to this topic.

None of the previous answers has answered the original question. Some have attempted to justify the lack of a constant, while others have showed ways in which we can deal with the lack of the constant. But no one has provided a compelling justification for the benefit of the constant, so its lack is still not properly explained.

A constant would be useful because it would prevent certain code errors from going unnoticed.

Say that you have a large code base with hundreds of references to "". Someone modifies one of these while scrolling through the code and changes it to " ". Such a change would have a high chance of going unnoticed into production, at which point it might cause some issue whose source will be tricky to detect.

OTOH, a library constant named EMPTY, if subject to the same error, would generate a compiler error for something like EM PTY.

Defining your own constant is still better. Someone could still alter its initialization by mistake, but because of its wide use, the impact of such an error would be much harder to go unnoticed than an error in a single use case.

This is one of the general benefits that you get from using constants instead of literal values. People usually recognize that using a constant for a value used in dozens of places allows you to easily update that value in just one place. What is less often acknowledged is that this also prevents that value from being accidentally modified, because such a change would show everywhere. So, yes, "" is shorter than EMPTY, but EMPTY is safer to use than "".

So, coming back to the original question, we can only speculate that the language designers were probably not aware of this benefit of providing constants for literal values that are frequently used. Hopefully, we'll one day see string constants added in Java.

Comments

-19

For those claiming "" and String.Empty are interchangeable or that "" is better, you are very wrong.

Each time you do something like myVariable = ""; you are creating an instance of an object. If Java's String object had an EMPTY public constant, there would only be 1 instance of the object ""

E.g: -

String.EMPTY = ""; //Simply demonstrating. I realize this is invalid syntax

myVar0 = String.EMPTY;
myVar1 = String.EMPTY;
myVar2 = String.EMPTY;
myVar3 = String.EMPTY;
myVar4 = String.EMPTY;
myVar5 = String.EMPTY;
myVar6 = String.EMPTY;
myVar7 = String.EMPTY;
myVar8 = String.EMPTY;
myVar9 = String.EMPTY;

10 (11 including String.EMPTY) Pointers to 1 object

Or: -

myVar0 = "";
myVar1 = "";
myVar2 = "";
myVar3 = "";
myVar4 = "";
myVar5 = "";
myVar6 = "";
myVar7 = "";
myVar8 = "";
myVar9 = "";

10 pointers to 10 objects

This is inefficient and throughout a large application, can be significant.

Perhaps the Java compiler or run-time is efficient enough to automatically point all instances of "" to the same instance, but it might not and takes additional processing to make that determination.

9 Comments

Wrong, according to stackoverflow.com/questions/1881922/… , the "" string will be reused from String pool.
I stated it might reuse the same object and if so, is still less efficient, because it needs to find that object (in the string pool), so how am I wrong? Regardless, there are several reason why String.Empty is superior, including preventing errors such as myVar = " "; and readability as well as the performance improvement I already stated. It is good practice to use constants instead of creating string literals, if for no other reason; it is easier to maintain code.
I doubt that your performance argument is valid because the JLS says that a constant will be treated as literal at compile time ( docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5 ). The readability is a better argument.
@AntonySmith - I guess you need to study Java a little more or perhaps you know your error by now. Java strings are immutable and in a pool. So there is only ONE String object for "" in a JVM, no matter how many times it is found in the code. You can check whether a string is empty by doing if (text == "")
Wrong. This comment should be deleted.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.