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

2018-12-31 15:32发布

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");

Because it creates unnecessary String objects. But instead it should be written like this:

String s = "No longer silly";

Ok fine so far...However, given this class:

public final class CaseInsensitiveString {
    private String s;
    public CaseInsensitiveString(String s) {
        if (s == null) {
            throw new NullPointerException();
        }
        this.s = s;
    }
    :
    :
}

CaseInsensitiveString cis = new CaseInsensitiveString("Polish");
String s = "polish";
  1. Why is the first statement ok? Shouldn't it be

    CaseInsensitiveString cis = "Polish";

  2. How do I make CaseInsensitiveString behave like String so the above statement is OK (with and without extending String)? What is it about String that makes it OK to just be able to pass it a literal like that? From my understanding there is no "copy constructor" concept in Java?

标签: java string
23条回答
永恒的永恒
2楼-- · 2018-12-31 15:57

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.

查看更多
像晚风撩人
3楼-- · 2018-12-31 15:59

The best way to answer your question would be to make you familiar with the "String constant pool". In java string objects are immutable (i.e their values cannot be changed once they are initialized), so when editing a string object you end up creating a new edited string object wherease the old object just floats around in a special memory ares called the "string constant pool". creating a new string object by

String s = "Hello";

will only create a string object in the pool and the reference s will refer to it, but by using

String s = new String("Hello");

you create two string objects: one in the pool and the other in the heap. the reference will refer to the object in the heap.

查看更多
春风洒进眼中
4楼-- · 2018-12-31 15:59

when they say to write

String s = "Silly";

instead of

String s = new String("Silly");

they mean it when creating a String object because both of the above statements create a String object but the new String() version creates two String objects: one in heap and the other in string constant pool. Hence using more memory.

But when you write

CaseInsensitiveString cis = new CaseInsensitiveString("Polish");

you are not creating a String instead you are creating an object of class CaseInsensitiveString. Hence you need to use the new operator.

查看更多
怪性笑人.
5楼-- · 2018-12-31 16:01

Java creates a String object for each string literal you use in your code. Any time "" is used, it is the same as calling new String().

Strings are complex data that just "act" like primitive data. String literals are actually objects even though we pretend they're primitive literals, like 6, 6.0, 'c', etc. So the String "literal" "text" returns a new String object with value char[] value = {'t','e','x','t}. Therefore, calling

new String("text"); 

is actually akin to calling

new String(new String(new char[]{'t','e','x','t'}));

Hopefully from here, you can see why your textbook considers this redundant.

For reference, here is the implementation of String: http://www.docjar.com/html/api/java/lang/String.java.html

It's a fun read and might inspire some insight. It's also great for beginners to read and try to understand, as the code demonstrates very professional and convention-compliant code.

Another good reference is the Java tutorial on Strings: http://docs.oracle.com/javase/tutorial/java/data/strings.html

查看更多
永恒的永恒
6楼-- · 2018-12-31 16:05

It is a basic law that Strings in java are immutable and case sensitive.

查看更多
不流泪的眼
7楼-- · 2018-12-31 16:05

Strings are special in Java - they're immutable, and string constants are automatically turned into String objects.

There's no way for your SomeStringClass cis = "value" example to apply to any other class.

Nor can you extend String, because it's declared as final, meaning no sub-classing is allowed.

查看更多
登录 后发表回答