看jdk的string类源代码:
public String toUpperCase(Locale locale) {
if (locale == null) {//偶不明白为什么这儿要判断一下,是否抛出空指针。因为空指针在运行的时候可以由jvm捕获的呀????
throw new NullPointerException();
} int firstLower; /* Now check if there are any characters that need to be changed. */
scan: {
for (firstLower = 0 ; firstLower < count; ) {
int c = (int)value[offset+firstLower];
int srcCount;
if ((c >= Character.MIN_HIGH_SURROGATE) &&
(c <= Character.MAX_HIGH_SURROGATE)) {
c = codePointAt(firstLower);
srcCount = Character.charCount(c);
} else {
srcCount = 1;
}
int upperCaseChar = Character.toUpperCaseEx(c);
if ((upperCaseChar == Character.ERROR) ||
(c != upperCaseChar)) {
break scan;
}
firstLower += srcCount;
}
return this;
} char[] result = new char[count]; /* may grow */
int resultOffset = 0; /* result may grow, so i+resultOffset
* is the write location in result */ /* Just copy the first few upperCase characters. */
System.arraycopy(value, offset, result, 0, firstLower); String lang = locale.getLanguage();
boolean localeDependent =
(lang == "tr" || lang == "az" || lang == "lt");
char[] upperCharArray;
int upperChar;
int srcChar;
int srcCount;
for (int i = firstLower; i < count; i += srcCount) {
srcChar = (int)value[offset+i];
if ((char)srcChar >= Character.MIN_HIGH_SURROGATE &&
(char)srcChar <= Character.MAX_HIGH_SURROGATE) {
srcChar = codePointAt(i);
srcCount = Character.charCount(srcChar);
} else {
srcCount = 1;
}
if (localeDependent) {
upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale);
} else {
upperChar = Character.toUpperCaseEx(srcChar);
}
if ((upperChar == Character.ERROR) ||
(upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
if (upperChar == Character.ERROR) {
if (localeDependent) {
upperCharArray =
ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale);
} else {
upperCharArray = Character.toUpperCaseCharArray(srcChar);
}
} else if (srcCount == 2) {
resultOffset += Character.toChars(upperChar, result, i + resultOffset) - srcCount;
continue;
} else {
upperCharArray = Character.toChars(upperChar);
} /* Grow result if needed */
int mapLen = upperCharArray.length;
if (mapLen > srcCount) {
char[] result2 = new char[result.length + mapLen - srcCount];
System.arraycopy(result, 0, result2, 0,
i + resultOffset);
result = result2;
}
for (int x=0; x<mapLen; ++x) {
result[i+resultOffset+x] = upperCharArray[x];
}
resultOffset += (mapLen - srcCount);
} else {
result[i+resultOffset] = (char)upperChar;
}
}
return new String(0, count+resultOffset, result);
}
且看jdk的stringbuffer的源代码: public synchronized int lastIndexOf(String str, int fromIndex) {
return String.lastIndexOf(value, 0, count,
str.toCharArray(), 0, str.length(), fromIndex);
} /**
* @since JDK1.0.2
*/
public synchronized StringBuffer reverse() {
super.reverse();
return this;
} public synchronized String toString() {
return new String(value, 0, count);
}
这儿方法为什么要用同步,用同步有什么好处,怎么就偏偏要在stringbuffer里面用同步呢?string就没有用。
public String toUpperCase(Locale locale) {
if (locale == null) {//偶不明白为什么这儿要判断一下,是否抛出空指针。因为空指针在运行的时候可以由jvm捕获的呀????
throw new NullPointerException();
} int firstLower; /* Now check if there are any characters that need to be changed. */
scan: {
for (firstLower = 0 ; firstLower < count; ) {
int c = (int)value[offset+firstLower];
int srcCount;
if ((c >= Character.MIN_HIGH_SURROGATE) &&
(c <= Character.MAX_HIGH_SURROGATE)) {
c = codePointAt(firstLower);
srcCount = Character.charCount(c);
} else {
srcCount = 1;
}
int upperCaseChar = Character.toUpperCaseEx(c);
if ((upperCaseChar == Character.ERROR) ||
(c != upperCaseChar)) {
break scan;
}
firstLower += srcCount;
}
return this;
} char[] result = new char[count]; /* may grow */
int resultOffset = 0; /* result may grow, so i+resultOffset
* is the write location in result */ /* Just copy the first few upperCase characters. */
System.arraycopy(value, offset, result, 0, firstLower); String lang = locale.getLanguage();
boolean localeDependent =
(lang == "tr" || lang == "az" || lang == "lt");
char[] upperCharArray;
int upperChar;
int srcChar;
int srcCount;
for (int i = firstLower; i < count; i += srcCount) {
srcChar = (int)value[offset+i];
if ((char)srcChar >= Character.MIN_HIGH_SURROGATE &&
(char)srcChar <= Character.MAX_HIGH_SURROGATE) {
srcChar = codePointAt(i);
srcCount = Character.charCount(srcChar);
} else {
srcCount = 1;
}
if (localeDependent) {
upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale);
} else {
upperChar = Character.toUpperCaseEx(srcChar);
}
if ((upperChar == Character.ERROR) ||
(upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
if (upperChar == Character.ERROR) {
if (localeDependent) {
upperCharArray =
ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale);
} else {
upperCharArray = Character.toUpperCaseCharArray(srcChar);
}
} else if (srcCount == 2) {
resultOffset += Character.toChars(upperChar, result, i + resultOffset) - srcCount;
continue;
} else {
upperCharArray = Character.toChars(upperChar);
} /* Grow result if needed */
int mapLen = upperCharArray.length;
if (mapLen > srcCount) {
char[] result2 = new char[result.length + mapLen - srcCount];
System.arraycopy(result, 0, result2, 0,
i + resultOffset);
result = result2;
}
for (int x=0; x<mapLen; ++x) {
result[i+resultOffset+x] = upperCharArray[x];
}
resultOffset += (mapLen - srcCount);
} else {
result[i+resultOffset] = (char)upperChar;
}
}
return new String(0, count+resultOffset, result);
}
且看jdk的stringbuffer的源代码: public synchronized int lastIndexOf(String str, int fromIndex) {
return String.lastIndexOf(value, 0, count,
str.toCharArray(), 0, str.length(), fromIndex);
} /**
* @since JDK1.0.2
*/
public synchronized StringBuffer reverse() {
super.reverse();
return this;
} public synchronized String toString() {
return new String(value, 0, count);
}
这儿方法为什么要用同步,用同步有什么好处,怎么就偏偏要在stringbuffer里面用同步呢?string就没有用。
解决方案 »
- JWebBrowser 打包后不显示地图
- 请教一下关于paint() paintComponent()和paintComponents()三个方法的区别
- 请问java随机读取txt中的几个人名
- 提一个关于线程的概念问题。
- 请问我用getInputStream()方法在Telnet服务器得到数据流后,怎样把得到数据流的文本内容保存到文档中呢?
- 关于log.xml在连接不上apache官方网站不通的情况下,无法加载的问题!!!!!
- //关于类中传递实例的问题,想不明白,为什么会这样.
- 【一个算法题,考脑子问题!】
- JNI使用入门问题,请指点
- 周一交差,大侠救命!!!!
- 数据库连接的 statement 对象生成后,但在两个不同的小模块中,如何调用。
- 有没有用过javaFX的
throw new NullPointerException();
}这个写错了吧,if (locale == null)
throw new IllegalArgumentException(locale );
}
还差不多
stringbuffer的同步是为了不同需要嘛,还有个不同步的stringbuffer就是StringBuilder
并且不进行参数验证的话,当运行到调用该参数时才会抛出异常,在此之前所有的工作都是
白作了!如果在开始处进行验证的话,马上就会进行参数验证,不符合要求的参数,下面的
代码一行都不执行了。
if (locale == null) {
throw new NullPointerException();
} int firstLower; /* Now check if there are any characters that need to be changed. */
scan: {
for (firstLower = 0 ; firstLower < count; ) {
int c = (int)value[offset+firstLower];
int srcCount;
if ((c >= Character.MIN_HIGH_SURROGATE) &&
(c <= Character.MAX_HIGH_SURROGATE)) {
c = codePointAt(firstLower);
srcCount = Character.charCount(c);
} else {
srcCount = 1;
}
int upperCaseChar = Character.toUpperCaseEx(c);
if ((upperCaseChar == Character.ERROR) ||
(c != upperCaseChar)) {
break scan;
}
firstLower += srcCount;
}
return this;
} char[] result = new char[count]; /* may grow */
int resultOffset = 0; /* Just copy the first few upperCase characters. */
System.arraycopy(value, offset, result, 0, firstLower); // 到这里才第一次用到,如果 locale 为 null 的话,前面这么一大段都是白做了,代价太大了
// 希望能理解 Java 类库开发人员为了提高无谓的劳动所做的一切
String lang = locale.getLanguage();
希望楼主不要有这种思想,异常是一种防止错误的机制,JVM 捕捉异常的代价比较高,能想得到的异常尽量自己处理,
能不让 JVM 处理就不让 JVM 处理。
StringBuffer并不是一般我们所说的工具类,它同步目的是为了在多个线程中同时使用时不会出现线程不安全问题。
而与它功能类似的StringBuilder就是为了只在同一个线程中使用或者不需要考虑线程安全时使用的
StringBuffer类根本不是工具类,它与String是同等地位的东西。它需要考虑如果被多个线程同时使用时可能出现的问题,所以才加同步
1,集合类,也有同步的方法,比如hashmap和hashtable。
2,字符串类。
他们都有个共同点,那就是内存对这种对象有大小限制。
字符串,是放在字符串池里面的,这个缓存区域是有限制的,所以就要考虑线程安全。
比如你stringbuilder的append方法,如果添加太多的字符串,结果会导致内存溢出。
集合类,当然是装对象的了,如果对象太多了,也会导致内存溢出。
但是StringBuilder不同,它会修改它内存的成员变量 char value[],如果线程A在append(str)调用过程还没有返回时,线程B同时调用了append(str2),就会导致StringBuilder内部的计算会出现问题,出现append丢失或者错位的问题而StringBuffer增加了同步,保证在线程A的append成功前,线程B不会进入方法,就可以保证两次的添加是正确的,不会出现丢失或者错位等问题、PS:你应该问的是,StringBuffer如果没有同步时会出现怎样的线程不安全问题,这样大家才能理解你的意思!
static StringBuilder buff = new StringBuilder(1);
public static void main(String[] args) throws Exception {
new Thread() {
public void run() {
buff.append("XXXXX");
}
}.start();
buff.append("CC");
System.out.println(buff);
}在某种情况下(你可以单步调试使得它必然出现),最后会打印出【CCXXX】,这就出现了append丢失了