我正在学习如何通过OCA考试,并坚持这个java字符串池的概念。
考虑以下几点:
public static void main(String[] args) {
String s1 = "Hello"; // since s1 and s2 are the same literal at compile-time, therefore they will be string pooled
String s2 = "Hello";
String s3 = "Hello".trim();
StringBuilder sb1 = new StringBuilder("Hello"); // although they are the same string, == only checks for object equality
StringBuilder sb2 = new StringBuilder("Hello");
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // true
System.out.println(sb1 == sb2); // false
}
s1
和s2
在字符串中是相同的,在对象中也是相同的,因为它是相同的字符串文本,所以JVM在编译时将字符串池s1
和s2
。
现在,s3
是在运行时计算的,因此应该返回一个新字符串。因此,s1==s3
应该为false,但事实并非如此。为什么?
我的一个理论是trim()
方法首先检查是否有空白需要删除,如果没有,则简单返回本身。这可以解释为什么s1==s3,但我不确定。
谢啦
以下是trim()的源代码。如果没有要删除的空白,则返回this
。因此,它与您trim
ed的参考相同。
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[st] <= ' ')) {
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}
如果您查看trim()
方法的源代码,您会发现在删除空格后,将调用子字符串(start,end)
。否则,如果没有空格,则返回相同的实例this
。
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[st] <= ' ')) {
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}
这里st
是删除空白后的开始索引,len
是新的长度。
现在,如果字符串前面或后面有空格:
String s1 = "hello "; //<-- whietspace at the end
System.out.println(s1.trim() == "hello");
当trim()
方法调用substring()
时,输出为false
。如果beginIndex
和endIndex
不相同,子字符串将返回一个新的字符串实例:
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
因此,在删除空格(如果有)后,beginIndex
和endIndex
将明显更改,并返回一个new String()
实例。
你是正确的。如果trim()方法不更改值,则将返回原始实例。如果所有的Hello都改为Hello,s3将不等于s1,因为trim()将删除空白并返回一个新的字符串实例。
问题内容: 当我使用定义变量时,该字符串不会添加到字符串池中,对吗? 现在,当我定义另一个而不是时,我将其定义为突然。(或我的大学老师说)。这是为什么?是什么使这个字符串突然变成字符串池字符串? 问题答案: 当我用new定义一个StringBuffer变量时,该字符串没有添加到字符串池中,对吗? 创建a 根本不会创建a 。 现在,当我定义另一个StringBuffer而不是new时,我突然将其定义
我的问题很简单。有什么区别-
看完这些讨论——问题1,问题2,文章 我对Java字符串常量池有以下理解(如果我错了,请纠正我): 编译源代码时,编译器会在我们的程序中查找所有字符串文字(放在双引号中的那些),并在堆区域中创建不同的(无重复)对象,并在称为字符串常量池(方法区域内的区域)的特殊内存区域中维护它们的引用。任何其他字符串对象都是在运行时创建的。 假设我们的代码有以下语句: 当编译上述代码时, 第1行:在堆中创建一个S
问题内容: 我尝试在Android上的Janino上使用这些东西,并得出结论说,它们根本无法在Dalvik VM中运行。 所以我只想问一个简单的问题:在 Android上 ,是否有可能在运行时编译包含代码的字符串以供应用程序使用。如果是这样,是否有让我这样做的库和/或您可以共享一个代码示例来做到这一点? 对于 (一个非常简单的) 示例,如果我有一个包含以下内容的String对象: 作为一根巨大的弦
对性能是否有影响? 不同Java版本的行为是否有差异?
问题内容: 假设字符串a和b: 在幕后,他们是同一回事吗? 这里将concat反编译为参考。我也希望能够反编译该+运算符,以查看其作用。 问题答案: 不,不是。 首先,语义上略有不同。如果a是null,则抛出一个,但a+=b将把原来的值a就好像它是null。此外,该方法仅接受值,而+操作员会将参数无提示地转换为String(使用对象的方法)。因此,该concat()方法在接受方面更加严格。 要深入