Friday, June 26, 2020

Best way to declare String in Java !!!

     String str = new String("SOME"); //always create a new object on the heap
     String str="SOME"; //uses the String pool

        //Try this small example:

        String s1 = new String("Hello");
        String s2 = "Hello";
        String s3 = "Hello";

        System.err.println(s1 == s2);
        System.err.println(s2 == s3);

To avoid creating unnecessary objects on the heap use the second form. 

 Q) Should I set the initial java String values from null to "" ? Often I have a class as such: 

    public class Foo { 
        private String s1;
        private String s2;
        // etc etc etc

This makes the initial values of s1 and s2 equal to null. Would it be better to have all my String class fields as follows? 

    public class Foo {
    private String s1 = "";
    private String s2 = "";
    // etc etc etc
Then, if I'm consistent with class definition I'd avoid a lot of null pointer problems. What are the problems with this approach? I disagree with the other posters. Using the empty string is acceptable. I prefer to use it whenever possible. In the great majority of cases, a null String and an empty String represent the exact same thing - unknown data. 

Whether you represent that with a null or an empty String is a matter of choice. The one place where you may need new String(String) is to force a substring to copy to a new underlying character array, as in 

    small = new String(huge.substring(10,20)) 
However, this behavior is unfortunately undocumented and implementation dependent. I have been burned by this when reading large files (some up to 20 MiB) into a String and carving it into lines after the fact. I ended up with all the strings for the lines referencing the char[] consisting of entire file. 

Unfortunately, that unintentionally kept a reference to the entire array for the few lines I held on to for a longer time than processing the file - I was forced to use new String() to work around it. The only implementation agnostic way to do this is: 

 small = new String(huge.substring(10,20).toCharArray()); 
This unfortunately must copy the array twice, once for toCharArray() and once in the String constructor. There needs to be a documented way to get a new String by copying the chars of an existing one; or the documentation of String(String) needs to be improved to make it more explicit (there is an implication there, but it's rather vague and open to interpretation). Pitfall of Assuming what the Doc Doesn't State In response to the comments, which keep coming in, observe what the Apache Harmony implementation of new String() was: 

    public String(String string) {
        value = string.value;
        offset = string.offset;
        count = string.count;
That's right, no copy of the underlying array there. And yet, it still conforms to the (Java 7) String documentation, in that it: Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable. The salient piece being "copy of the argument string"; it does not say "copy of the argument string and the underlying character array supporting the string". 


Post a Comment


Get in touch with me


Bangalore, India