1

It's a pretty naive question to ask but I got this doubt while programming for Android. I use to initialize my new strings like String a=null, so in my code there remains a probability to get NullPointerException if I forget to initialize the variable before accessing it but what about the other case. Also which one should be used?

Tulains Córdova
  • 39,201
  • 12
  • 97
  • 154
Rajat Saxena
  • 121
  • 1
  • 1
  • 7
  • 7
    That completely depends on the context of the code. Sometimes you'd rather have a NPE rather than doing a mistaken operation on an empty string and thinking everything is ok. Ideally though, you don't have *either*, but that will require you to write the code appropriately. –  Jul 27 '15 at 16:07
  • The difference is that you'll get an empty string in the other case rather than `null`. – dramzy Jul 27 '15 at 16:07
  • Empty strings take more space and time anyway and might confuse the reader of your code about what you're doing with it further down. (They might think you're probably concatenating onto it later or something.) – Panzercrisis Jul 27 '15 at 16:08
  • @Panzercrisis If the empty string is created with `String foo = "";` they are all interned and take no additional space. If you are for some reason doing `new String()`, any reasonable static analysis or code review will flag it as "don't do this" for very good reason. I've only very rarely seen good reason to use `new String()`. –  Jul 27 '15 at 16:09
  • So it means that `String a= null` is a way to go? – Rajat Saxena Jul 27 '15 at 16:09
  • 1
    Just to add to the confusion: `null` is widely considered a billion-dollar mistake. It was created because it's so easy to implement, but it introduces an unnecessary special case into program logic that causes endless troubles. If at all possible, try to program as if `null` didn't exist and avoid all this trouble. This means paying the price for an occasional `""` here and there, but nowadays this is a good trade-off even in the small environment of mobile devices. – Kilian Foth Jul 27 '15 at 16:11
  • @KilianFoth: Can you please guide me to some blog post or documentation link where I can read more about this `null` thing? – Rajat Saxena Jul 27 '15 at 16:13
  • 1
    @RajatSaxena [Are null references really a bad thing?](http://programmers.stackexchange.com/questions/12777/are-null-references-really-a-bad-thing) –  Jul 27 '15 at 16:14
  • @MichaelT What's the TL;DR? The guy in the video just kind of keeps rambling, and it seems like not having the distinction between `null` and `""` (or new `Object()`) would run its own risk of mistakes. – Panzercrisis Jul 27 '15 at 16:18
  • 1
    @Panzercrisis Correct - I don't completely agree with it. However, if one lacks the discipline and instead writes sloppy code NPE pop up everywhere (and thus the billion dollar mistake). If one is going to be undisciplined with assignments and tests, then the NullObject pattern is probably safer to use. –  Jul 27 '15 at 16:22
  • @MichaelT So if I do something like `String a= new String()` and then `a = "Harry"` ,in this case the object created by `new String()` will be lost? – Rajat Saxena Jul 27 '15 at 16:23
  • 2
    The object allocated by `new String()` would be garbage collected as there are likely no other references to it. Why one does this as a two statements, I don't know. Why not `String a = "Harry";` in the first place? Or leave it unassigned until you actually use it? –  Jul 27 '15 at 16:25
  • If at all possible, try to write something like `final String x = "the string";`. This way: a- `x` cannot be null, and b- `x` is guaranteed not to change its value during its scope, avoiding nasty surprises. – Andres F. Aug 06 '15 at 02:49

3 Answers3

11

First let's clarify something: You mention that after assigning null to the variable you could forget to initialize it, but by assigning null to it you are in effect initializing it.

public static void main (String args[]){
    String s;       
    System.out.println(s); // compiler error variable may not be initialized
}

vs

public static void main (String args[]){
    String s=null;      
    System.out.println(s); // no compiler error
    System.out.println(s.equals("helo")); // but this will generate an exception
}

So after you do String s=null; there's is no way that you could forget to initialize because you did initialize it.

That being clear, I would recommend you to use a "smart default". In your case perhaps the empty string "" would be a good default value if you want to avoid NullPointerException. In the other hand, sometimes it is desirable that the program produce an exception because it indicates something wrong happened under the hood that should not have happened.

Tulains Córdova
  • 39,201
  • 12
  • 97
  • 154
  • 2
    Agreed. But also, if the OP doesn't need to change `s`, they should initialize it once and make it final. No need to mess with `null` or empty Strings :) – Andres F. Aug 06 '15 at 02:51
8

In general you want to keep declaration and initialisation as close as possible to minimise exactly the type of problem you're talking about.

There is also the issue of redundant initialisation where the value null you're assigning is never used which is extra code that harms readability even if the redundant assignment is optimised away by the compiler.

Sometimes assigning some sort of default value is unavoidable, for example if you declare before a try catch, initialise inside and use it afterwards. For other types you can often find a more natural default value such as an empty list.

DavidTheWin
  • 181
  • 2
  • 1
    It is avoidable, just rethrow in catch blocks, and compiler would understand that there are no branches leaving variable uninitialized after the block. – Basilevs Dec 16 '16 at 02:44
0

There are two different views of "initialisation". One is that a variable has a defined value after initialisation. One is that a variable has a useful value. Neither setting this variable to null or to new String () will set it to a useful value.

Using the variable is a bug, whether it is uninitalised or just not set to something useful. The compiler is very good at finding situations where a variable is used while uninitialised (and doesn't allow it). But by setting the variable to null or new String (), you remove the compiler's ability to tell you when there is no useful value. For example:

String a = null;
if (condition1) a = "Yes";
else if (condition2) a = "No";

If neither condition is true, a isn't set to anything useful, but the compiler can't tell you about it anymore. So we have a bug, but you destroyed the compilers ability to report it. If you hadn't initialised a, the compiler would tell you.

gnasher729
  • 42,090
  • 4
  • 59
  • 119