//String.replaceAll 接受了一个正则表达式作为它的第一个参数,而并非接受了一个字符序列字面常量。 //正则表达式“.”可以匹配任何单个的字符,要想只匹配句点符号,在正则表达式中的句点必须在其前面添加 //一个反斜杠(\)进行转义。 System.out.println(Puzzlers.class.getName().replaceAll(".", "/") + ".class"); //输出为://///////////////////////////////////.class System.out.println(Puzzlers.class.getName().replaceAll("\\.", "/") + ".class"); //输出为:com/jaeson/javastudy/puzzler/Puzzlers.class //在替代字符串中出现的反斜杠会把紧随其后的字符进行转义,从而导致其被按字面含义而处理了。 //Exception:String index out of range try { System.out.println(Puzzlers.class.getName().replaceAll("\\.", File.separator) + ".class"); } catch (StringIndexOutOfBoundsException ex) { System.out.println("StringIndexOutOfBoundsException: " + ex.getMessage()); } //使用1.5新的replace方法:它将模式和替代物都当作字面含义的字符串处理。 System.out.println(Puzzlers.class.getName().replace(".", File.separator) + ".class");
//每当你要将一个byte 序列转换成一个String 时,你都在使用某一个字符集,不管你是否显式地指定了它。 //如果你想让你的程序的行为是可预知的,那么就请你在每次使用字符集时都明确地指定。 byte bytes[] = new byte[256]; for (int j = 0; j < 256; j++) bytes[j] = (byte) j; try { //不指定字符集时使用的是平台的缺省字符集,输出是不可预知的 System.out.println(new String(bytes)); //正确的用法 System.out.println(new String(bytes, "ISO-8859-1")); } catch (UnsupportedEncodingException ex) {}
//String类型的编译期常量是内存限定的。 //任何两个String 类型的常量表达式,如果标明的是相同的字符序列,那么它们就用相同的对象引用来表示。 //+ 操作符,不论是用作加法还是字符串连接操作,它都比 == 操作符的优先级高。 final String pig = "length: 10"; final String dog = "length: " + pig.length(); System.out. println("Animals are equal: " + pig == dog); //false //相当于执行下面的语句: System.out. println(("Animals are equal: " + pig) == dog); System.out.println("Animals are equal: " + (pig == dog)); //Animals are equal: false //正确的做法: System.out.println("Animals are equal: " + pig.equals(dog)); //Animals are equal: true
//char 数组不是字符串。要想将一个char 数组转换成一个字符串,就要调用String.valueOf(char[])方法。 //否则进行+字符串连接操作时会调用Object.toString()。 System.out.println(new char[] { '1', '2', '3' }); //123 System.out.println("" + new char[] { '1', '2', '3' }); //[C@191c0b76
//使用字符串连接操作符使用格外小心。+ 操作符当且仅当它的操作数中至 //少有一个是String 类型时,才会执行字符串连接操作;否则,它执行的就是加法。 //编译器在计算常量表达式'H'+'a'时,是通过我们熟知的拓宽原始类型转换将两 //个具有字符型数值的操作数('H'和'a')提升为int 数值而实现的。 System.out.println('H' + 'a'); //169 System.out.println("2 + 2 = " + 2 + 2); //2 + 2 = 22
//在字符串和字符字面常量中要优先选择转义字符序列,而不是Unicode 转义字符。 //除非确实是必需的,否则就不要使用Unicode 转义字符。 //Java 对在字符串字面常量中的Unicode 转义字 符没有提供任何特殊处理。 //编译器在将程序解析成各种符号之前,先将Unicode转义字符转换成为它们所表示的字符。 // \u0022 是双引号的Unicode 转义字符 System.out.println("a\u0022.length()+\u0022b".length()); //2 //可以使用转义字符序列来实现: 转义字符序列是一个反斜杠后面紧跟着一个需要转义的字符 System.out.println("a\".length()+\"b".length()); //14
/** * c:\u2222test */ //(\ u)表示的是一个Unicode 转义字符的开始。这些字符后面必须紧跟四个十六进制的数字。 //否则编译器被要求拒绝该程序。Unicode 转义字符必须是良构的,即使是出现在注释中也是如此。 //要确保字符\ u 不出现在一个合法的Unicode 转义字符上下文之外, //即使是在注释中也是如此。在机器生成的代码中要特别注意此问题。 //Unicode 转义字符只有在你要向程序中插入用其他任何方式都 //无法表示的字符时才是必需的,除此之外的任何情况都不应该避免使用它们。 //下面Unicode代码相当于:System.out.println("Hello w"+"orld"); //输出Hello world \u0053\u0079\u0073\u0074\u0065\u006d\u002e\u006f\u0075\u0074 \u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0020 \u0022\u0048\u0065\u006c\u006c\u006f\u0020\u0077\u0022\u002b \u0022\u006f\u0072\u006c\u0064\u0022\u0029\u003b