‘M’去哪儿了?
我用String Buffer玩了一下,注意到混合字符和字符串是一个坏主意。 我希望我的下面的代码可以打印“Main”,但是只是得到了一个“ain”。
很明显,word是使用String Buffer构造函数的char版本初始化的,但是我测试了几个方法,比如toString或getIndex(),但是在“ain”旁边找不到任何东西 – 这让我想知道:构造函数做了什么? 它有用吗? 可以通过单词再次检索“M”吗?
import java.util.Random; public class OrNotPublicClass { private static Random rnd = new Random(); public static void main(String[] args) { StringBuffer word = null; switch (rnd.nextInt(2)) { case 1: word = new StringBuffer('P'); case 2: word = new StringBuffer('G'); default: word = new StringBuffer('M'); } word.append("ain"); System.out.println(word); } }
除了break
问题,这里的主要问题是如何初始化StringBuffer
。
没有构造函数接受char
作为参数, 但是有一个接受一个int
作为容量 。
那是你用的那个……
你应该做:
word = new StringBuilder(); // not StringBuffer // switch. Then: word.append("ain");
(还要注意使用StringBuilder
而不是StringBuffer
;后者仅在需要线程安全的极少数情况下才有用)
您的代码的问题非常简单:
new StringBuffer('M')
不会按照您的想法执行。 StringBuffer
中没有构造函数需要char
。 而是调用此构造函数: StringBuffer(int capacity)
,其中char
被隐式转换为int
。
所以基本上你的代码不会创建一个包含单个字符的新StringBuffer
,而是一个容量与给定字符匹配的StringBuffer
。
但是还有其他一些问题,比如在每个case
结束时遗漏break
,所以在switch语句之后, word
将始终是new StringBuffer('M');
这个编译的原因是原始扩展转换。 基本上任何积分数据类型都可以转换为另一种积分数据类型,只要转换是无损耗即可。 以下是一些进一步阅读的链接:
StringBuffer文档
原始拓宽 – JLS
它使用StringBuffer
的int
构造函数来设置初始缓冲区的容量。
为什么使用int构造函数? 它与扩展原始转换有关 。
没有StringBuffer构造函数接受char。 这里发生的是Java已经进行了扩展的原始转换 ,将char
转换为int
,然后创建了初始容量为77
的StringBuffer
。
但是,有一个接受String
的构造函数,您可以使用它来解决您的问题:
StringBuffer buffer = new StringBuffer("M");
无论如何,还建议您使用StringBuilder
,它被设计为在单个线程使用字符串缓冲区的地方更快地替换StringBuffer
。