Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Why didn't Java designers create static versions of string manipulation methods in the java.lang.String class? The following methods are what I refer to, but the question can be extended to other non-static methods in the class as well.

concat(String)                        substring(int, int)
replace(char, char)                   toLowerCase()
replace(CharSequence, CharSequence)   toLowerCase(Locale)
replaceAll(String, String)            toString()
replaceFirst(String, String)          toUpperCase()
split(String)                         toUpperCase(Locale)
split(String, int)                    trim()
substring(int)

Having only non-static versions of these methods forces explicit null-checking anywhere such a method has to be called. For example, simply calling example = example.trim() would lead to NullPointerException if String example = null. So the programmer has to do the following boilerplate null check:

if (example != null)
    example = example.trim();
// OR:
example = (example==null) ? null : example.trim();
example = (example==null) ? null : example.substring(5);

I would imagine it would have been a lot more convenient if String had static versions of these methods (perhaps even exclusively), which would take the input string as the first argument:

example = String.trim(example);
example = String.replace(example, 'a', 'b');
example = String.substring(example, 5);

This would have led to cleaner code written by programmers which would have automatically taken care of null cases by simply returning null, rather than forcing programmers to explicitly handle null cases. The returning of null makes sense to me since manipulating a null string should result in a null string, not an error.

Why didn't Java designers think of this when they designed the String class in Java 1 or Java 2, or even add such a functionality in a later Java version?

share|improve this question
14  
I would suggest replacing "Why didn't Java designers think of X" with "Why did Java designers decide against X". Give them the basic credit of not being blind to the option. –  Avner Shahar-Kashtan Dec 12 '13 at 8:06
3  
null is an exceptional state and should be handled explicitly. –  CodesInChaos Dec 12 '13 at 8:56
2  
@KonradMorawski: Personally I find that a gross misuse of extension methods. If you have a null value then what on earth are you doing trying to call methods on it, you're just going to confuse everyone who reads that code. It's a poor reimplementation of a Maybe<T> type, I guess? –  Phoshi Dec 12 '13 at 9:29
1  
@Phoshi one has to keep in mind that extension methods are NOT real methods, they're just syntax sugar. But I agree that it's controversial. I wish C# / Java offered some sort of built-in syntactic null-safety, like - say - Kotlin. string name = employee?.personalData?.name. Just as a shortcut for all these repetitive if (employee != null)s. Related SO question: stackoverflow.com/questions/1196031/… –  Konrad Morawski Dec 12 '13 at 9:39
1  
@KonradMorawski: Correct, however they look like real methods. When reading the code without the knowledge they're extension methods it's gonna be really really confusing. Side note, that null safe dot operator is apparently an upcoming feature for C#, so you'll get your wish. Along with the null coalescing operator (??) it should make nulls much easier to work with, though personally I'd still prefer a first class Maybe type that's not gonna happen at this stage in the language's life. –  Phoshi Dec 12 '13 at 9:42
show 11 more comments

4 Answers

The returning of null makes sense to me since manipulating a null string should result in a null string, not an error

Well, that is your opinion. Others may argument that String operations on a null object, which does not contain a String, make no sense and hence should throw an Exception

Why "Java designers" did or did not something is difficult to anwer.

There are already libraries out there which can do null-safe String operations, e.g. StringUtils of Apache Commons. You can use that or similar libraries if you need them.


Addition based on your comments

Reading through the comments, it seems like the real problem you face is that you have to check for null all over your code. That can be an indicator of a bad program design without clearly defined contracts between interfaces. You might want to read Avoiding “!= null” statements in Java?

share|improve this answer
1  
Thanks for your feedback. I guess the real question is, why do we have to depend on an external library or home-brewed classes when such a basic feature can be made part of standard Java? –  ADTC Dec 12 '13 at 8:02
4  
@ADTC let's put the question the other way round: Why should "Java designers" include something into the language, if there are already lots of good libraries out there, well tested and documented? How to define a "basic feature" is opinion based. Doesn't mostly every project need some external library for "Basic functionality" (unit testing, mocking, date and time,...)? It ain't a big deal, is it? –  Uooo Dec 12 '13 at 8:13
    
One way of dealing with nulls is using Guava's Optional - code.google.com/p/guava-libraries/wiki/… –  Konrad Morawski Dec 12 '13 at 12:32
add comment

IMO the whole "if arg is null return null" approach to writing methods needlessly increases the cyclomatic complexity of your program.

Early Java libs used the return null approach, but the JDK guys always guarded against null with exceptions.

With time, I think the latter approach has come out as the clear winner.

Why? Since null fields break a lot of oo principles. You simply cannot treat them as members of a polymorphic class. This means that you always have to code special cases for null, and hence your cyclomatic complexity soars when you have to assume that things can be null.

In order to solve your problems, consider using the null object pattern instead of relying on null fields.

share|improve this answer
2  
But String is not polymorphic, no? And how do you use the null object pattern for an already existing type like String? –  svick Dec 12 '13 at 9:05
    
String is not polymorphic, no. But even so you would like to know that you can call instance methods on any string reference that you have. This works for all non-null references. String already has a null object: the empty string. Just like lists have the empty list. So ask yourself why the empty string isn't enough in your case. I guess that you use a null string to flag some special case. Ask yourself if you can use a separate flag for that special case. –  Alexander Torstling Dec 12 '13 at 15:27
    
@AlexanderTorstling: A field of type int defaults to zero rather than null. Conceptually it should be possible to have a string type whose default value would be an empty string rather than null [such a type could semantically be to String what int is to Integer]. The fact that a non-empty string would internally hold a reference to a heap object would be an implementation detail; there's no reason it couldn't behave semantically like a primitive. –  supercat Dec 23 '13 at 19:29
    
@supercat: Agreed. I think it would have been better to forbid null values for refefences unless explicitly enabled. Default non-null and final fields. Many types already have null behaviour objects –  Alexander Torstling Dec 25 '13 at 11:32
    
@AlexanderTorstling: Having storage locations of all types default to all-bytes-zero, and providing that structure types can be assigned via all-bytes-copy, greatly simplifies a framework, but pretty much implies that types with mutable reference semantics must default to null. It would have been helpful, however, to have had framework support for value types which would encapsulate a single reference and would "box" as--and could unbox from--that reference type. –  supercat Dec 25 '13 at 19:59
add comment

Not saying this is the reason, but except for toString, all of these methods are easily encapsulated in a static helper class, while the reverse is not true.

I.e. if you want Stings.toUpper(string input) the code for that is easy to write, but if you want instance.toUpper and all you have is String.toUpper, well, that is impossible...unless they introduce extension methods, which most likely wasn't even considered at the time.

share|improve this answer
    
Good point, although more of a comment than an answer. But even given that, why do we have to depend on an external library or home-brewed classes when such a basic feature can be made part of standard Java? –  ADTC Dec 12 '13 at 7:59
1  
As of now, you do have String.format (static), but you can't do "something %s".format(id). –  Konrad Morawski Dec 12 '13 at 11:09
    
@adtc: because it's not a basic feature of the language to do it via a static class. Starting from that premise, there's a lot of reasons not to do so - unnecessary code/code bloat, duplicate functionality, cost of development/maintenance. –  jmoreno Dec 12 '13 at 16:25
add comment

In java, that string is an object. That's a design choice.

Object references can be null and are null if there is no object assigned to it. If you call such an object, a NullPointerException is thrown. That's standard oo-behaviour.

Java designers made the choice of having strings as object and having those methods throwing null-pointer exceptions is what you get if you want strings to be objects.

Why didn't Java designers think of this when they designed the String class in Java 1 or Java 2, or even add such a functionality in a later Java version?

They probably did think about it and chose to incorporate oo-behaviour.

share|improve this answer
    
May I know, how is creating static methods to take care of null cases not OO behavior? To be clear, I'm not saying it is, but I'm trying to understand why you say the design decision is to incorporate OO behavior. –  ADTC Dec 12 '13 at 9:40
    
Static methods are more like functions. And for the use you want they shouldn't even be part of the string class rather be part of some utility class. Just like math class functions. –  Pieter B Dec 12 '13 at 9:58
3  
Just because strings are objects doesn't mean that the String class can't have static methods. And indeed it has some already, eg. String.format. (Same in C#, by the way). So if that's a design choice, it can't come solely from the fact that strings are objects, and it's not applied consistently. –  Konrad Morawski Dec 12 '13 at 11:04
    
@PieterB I wouldn't complain if at least such methods were provided in a Strings utility class, like we have Arrays utility class (although I understand it was created out of sheer necessity due to arrays being some sort of a weird cross between primitives and objects :)).. as long as it was part of standard Java and didn't require dependencies. –  ADTC Dec 14 '13 at 7:59
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.