Java Strings: “String s = new String(”silly“);”

前端 未结 23 2394

I\'m a C++ guy learning Java. I\'m reading Effective Java and something confused me. It says never to write code like this:

String s = new String(\"silly\");         


        
相关标签:
23条回答
  • 2020-11-22 14:47

    Strings are treated a bit specially in java, they're immutable so it's safe for them to be handled by reference counting.

    If you write

    String s = "Polish";
    String t = "Polish";
    

    then s and t actually refer to the same object, and s==t will return true, for "==" for objects read "is the same object" (or can, anyway, I"m not sure if this is part of the actual language spec or simply a detail of the compiler implementation-so maybe it's not safe to rely on this) .

    If you write

    String s = new String("Polish");
    String t = new String("Polish");
    

    then s!=t (because you've explicitly created a new string) although s.equals(t) will return true (because string adds this behavior to equals).

    The thing you want to write,

    CaseInsensitiveString cis = "Polish";
    

    can't work because you're thinking that the quotations are some sort of short-circuit constructor for your object, when in fact this only works for plain old java.lang.Strings.

    0 讨论(0)
  • 2020-11-22 14:47
    String s1="foo";
    

    literal will go in pool and s1 will refer.

    String s2="foo";
    

    this time it will check "foo" literal is already available in StringPool or not as now it exist so s2 will refer the same literal.

    String s3=new String("foo");
    

    "foo" literal will be created in StringPool first then through string arg constructor String Object will be created i.e "foo" in the heap due to object creation through new operator then s3 will refer it.

    String s4=new String("foo");
    

    same as s3

    so System.out.println(s1==s2);// **true** due to literal comparison.

    and System.out.println(s3==s4);// **false** due to object

    comparison(s3 and s4 is created at different places in heap)

    0 讨论(0)
  • 2020-11-22 14:47

    If I understood it correctly, your question means why we cannot create an object by directly assigning it a value, lets not restrict it to a Wrapper of String class in java.

    To answer that I would just say, purely Object Oriented Programming languages have some constructs and it says, that all the literals when written alone can be directly transformed into an object of the given type.

    That precisely means, if the interpreter sees 3 it will be converted into an Integer object because integer is the type defined for such literals.

    If the interpreter sees any thing in single quotes like 'a' it will directly create an object of type character, you do not need to specify it as the language defines the default object of type character for it.

    Similarly if the interpreter sees something in "" it will be considered as an object of its default type i.e. string. This is some native code working in the background.

    Thanks to MIT video lecture course 6.00 where I got the hint for this answer.

    0 讨论(0)
  • 2020-11-22 14:47

    In Java the syntax "text" creates an instance of class java.lang.String. The assignment:

    String foo = "text";
    

    is a simple assignment, with no copy constructor necessary.

    MyString bar = "text";
    

    Is illegal whatever you do because the MyString class isn't either java.lang.String or a superclass of java.lang.String.

    0 讨论(0)
  • 2020-11-22 14:51

    In most versions of the JDK the two versions will be the same:

    String s = new String("silly");

    String s = "No longer silly";

    Because strings are immutable the compiler maintains a list of string constants and if you try to make a new one will first check to see if the string is already defined. If it is then a reference to the existing immutable string is returned.

    To clarify - when you say "String s = " you are defining a new variable which takes up space on the stack - then whether you say "No longer silly" or new String("silly") exactly the same thing happens - a new constant string is compiled into your application and the reference points to that.

    I dont see the distinction here. However for your own class, which is not immutable, this behaviour is irrelevant and you must call your constructor.

    UPDATE: I was wrong! Based on a down vote and comment attached I tested this and realise that my understanding is wrong - new String("Silly") does indeed create a new string rather than reuse the existing one. I am unclear why this would be (what is the benefit?) but code speaks louder than words!

    0 讨论(0)
提交回复
热议问题