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