Java 不是文本的字符串对象不需要新关键字?

Java 不是文本的字符串对象不需要新关键字?,java,string,new-operator,Java,String,New Operator,所以我知道还有其他类似的问题,比如和。但他们的答案似乎是,因为它们是文字,并且是不可变文字常量池的一部分,所以它们仍然可用。这对我来说是有意义的,但是为什么非文字也可以正常工作呢?在处理字符串时,我什么时候必须使用“new”关键字。在下面的例子中,我使用字符串来做一些事情,但是一切都很好,我从不使用“new”关键字(更正:我从不将它用于字符串类型的对象) 字符串在Java中是专门处理的。Java JVM使用了一种称为字符串池的类似缓存的实现 与其他对象不同,当您创建如下文本字符串时:String

所以我知道还有其他类似的问题,比如和。但他们的答案似乎是,因为它们是文字,并且是不可变文字常量池的一部分,所以它们仍然可用。这对我来说是有意义的,但是为什么非文字也可以正常工作呢?在处理字符串时,我什么时候必须使用“new”关键字。在下面的例子中,我使用字符串来做一些事情,但是一切都很好,我从不使用“new”关键字(更正:我从不将它用于字符串类型的对象)


字符串在Java中是专门处理的。Java JVM使用了一种称为字符串池的类似缓存的实现

与其他对象不同,当您创建如下文本字符串时:
String mystring=“Hello”Java将首先检查字符串“Hello”是否已经存在于字符串池中。如果没有,它会将其添加到缓存中,并在再次引用时重新使用

因此,当您第一次将变量分配给“Hello”时,它会被添加到池中:

String s1 = "Hello";
String s2 = "Hello";
String s3 = s1;
s1 = "SomethingElse"
在上面的代码中,当s1被指定为“Hello”时,JVM将看到它没有存储在池中,并将其创建/添加到池中。 对于s2,您再次引用“Hello”。JVM将在池中看到它,并将s2分配给存储在池中的相同字符串。s3被简单地分配给在s1的内存地址处引用的值,或者相同的字符串“Hello”。最后,s1被重新分配给另一个字符串,该字符串在池中还不存在,因此被添加。此外,s1不再指向“Hello”,但它不会被垃圾收集,原因有二。1:t存储在字符串池中,2:s2也指向相同的引用字符串


对于字符串,决不能使用
new
关键字来创建文字字符串。如果这样做,您就没有利用字符串池重用,并且可能会导致同一字符串的多个实例存在于内存中,这是一种浪费。

字符串在Java中是专门处理的。Java JVM使用了一种称为字符串池的类似缓存的实现

与其他对象不同,当您创建如下文本字符串时:
String mystring=“Hello”Java将首先检查字符串“Hello”是否已经存在于字符串池中。如果没有,它会将其添加到缓存中,并在再次引用时重新使用

因此,当您第一次将变量分配给“Hello”时,它会被添加到池中:

String s1 = "Hello";
String s2 = "Hello";
String s3 = s1;
s1 = "SomethingElse"
在上面的代码中,当s1被指定为“Hello”时,JVM将看到它没有存储在池中,并将其创建/添加到池中。 对于s2,您再次引用“Hello”。JVM将在池中看到它,并将s2分配给存储在池中的相同字符串。s3被简单地分配给在s1的内存地址处引用的值,或者相同的字符串“Hello”。最后,s1被重新分配给另一个字符串,该字符串在池中还不存在,因此被添加。此外,s1不再指向“Hello”,但它不会被垃圾收集,原因有二。1:t存储在字符串池中,2:s2也指向相同的引用字符串

对于字符串,决不能使用
new
关键字来创建文字字符串。如果这样做,则不会利用字符串池重用,可能会导致内存中存在同一字符串的多个实例,这是一种浪费。

以下几点: “旧”这个词在这里被收集了吗?” 你的编译器很可能意识到它从未被使用过,只是完全跳过了它

Scanner::nextLine
返回一个
字符串
,方法返回的值用于赋值

至于何时使用
new
作为
String
s。。。嗯,很少可能是最好的。我唯一一次看到它被用于内部常数。比如说

public class MatchChecker {
    private static final String ANY_VALUE = new String("*");

    private final Map<Object, String> map = new HashMap<Object, String>();

    public void addMatch(Object object, String string) {
        map.put(object, string);
    }

    public void addAnyValueMatch(Object object) {
        map.put(object, ANY_VALUE);
    }

    public boolean matches(Object object, String string) {
        if (!map.contains(object)) {
            return false;
        }
        if (map.get(object) == ANY_VALUE || map.get(object).equals(string)) {
            return true;
        }
        return false;
    }
}
公共类匹配检查器{
私有静态最终字符串ANY_值=新字符串(“*”);
私有最终映射=新HashMap();
public void addMatch(对象、字符串){
map.put(对象、字符串);
}
public void addAnyValueMatch(对象){
map.put(对象,任意_值);
}
公共布尔匹配(对象、字符串){
如果(!map.contains(对象)){
返回false;
}
if(map.get(object)==任何_值| | map.get(object).equals(string)){
返回true;
}
返回false;
}
}
这意味着只有通过
addAnyValueMatch
添加的对象才会匹配任何值(使用
=
进行测试),即使用户使用
“*”
作为
addMatch

中的字符串有两点: “旧”这个词在这里被收集了吗?” 你的编译器很可能意识到它从未被使用过,只是完全跳过了它

Scanner::nextLine
返回一个
字符串
,方法返回的值用于赋值

至于何时使用
new
作为
String
s。。。嗯,很少可能是最好的。我唯一一次看到它被用于内部常数。比如说

public class MatchChecker {
    private static final String ANY_VALUE = new String("*");

    private final Map<Object, String> map = new HashMap<Object, String>();

    public void addMatch(Object object, String string) {
        map.put(object, string);
    }

    public void addAnyValueMatch(Object object) {
        map.put(object, ANY_VALUE);
    }

    public boolean matches(Object object, String string) {
        if (!map.contains(object)) {
            return false;
        }
        if (map.get(object) == ANY_VALUE || map.get(object).equals(string)) {
            return true;
        }
        return false;
    }
}
公共类匹配检查器{
私有静态最终字符串ANY_值=新字符串(“*”);
私有最终映射=新HashMap();
public void addMatch(对象、字符串){
map.put(对象、字符串);
}
public void addAnyValueMatch(对象){
map.put(对象,任意_值);
}
公共布尔匹配(对象、字符串){
如果(!map.contains(对象)){
返回false;
}
if(map.get(object)==任何_值| | map.get(object).equals(string)){
返回true;
}
返回false;
}
}
这意味着只有通过
addAnyValueMatch
添加的对象才会匹配任何值(使用
=
进行测试),即使用户使用
“*”
作为
addMatch
中的字符串<