字符串操作可能是计算机程序设计中最常见的行为之一. 而我们常见的字符串类型有String类,StringBuffer类和StringBuilder类. 其中,String类型代表的是一个不可变的字符串类型,而StringBuffer是一个线程安全的可变字符串序列. StringBuilder类是一个可变的字符串序列,但是并不是线程安全的,性能上比StringBuffer好,可以说是在单线程中的StringBuffer的一个理想代替.
不可变的String
String类型是不可变的. String类型是不可变的. String类型是不可变的. 所有看上去修改了String类型的操作实际上都是创建了一个新的String实例. 同时String类型的equals方法也被重写了,使得当String类型的”值”一样的时候,equals判断就为真. 这更符合人类对字符串的理解. 但同时也会给String是不可变的这一特性的理解带来一定的困扰.
1.public class Immutable {
2. public static String upcase(String s){
3. return s.toUpperCase();
4. }
5. public static void main(String[] args) {
6. String str="hello";
7. System.out.println(str);
8. String str2 = upcase(str);
9. System.out.println(str2);
10. }
11.}/*output:
12.hello
13.HELLO
14.*/
这是一个简单的例子,没有什么太多好说的. 只有一点,str2的操作,实际上是在内存中新开辟一个区域,然后存入转换后的字符串. 用python的话说,这不是一个”原地操作”.
重载”+”和StringBuilder
java是不允许操作符重载的. 但是java给了两个特例,那就是字符串操作中的”+”和”+=”
首先,一定要接受一个事实,String类型是不可变的. 那么问题来了,因为String类型是不可变的,那由此带来的每次String相关的一些操作在效率上就会存在问题. 比如字符串连接"hey"+"hello"+"world"
这个操作应该要如何进行. 假设String类型有个append()方法,那么先创建一个内存区域,存放”hey”和”hello”连接后的字符串假设叫str1,这是一个中间对象,然后在整一个新的内存区域,存放str1和”world”连接后的字符串. 如果说有大量的这种字符串连接操作,那么就会产生大量的中间对象. 显然这种方式开销是很大的.
那么java实际上是不是这么做的呢?据埃大爷说java早期真的是这么做的.(我年纪小,没有经历过这些,捂脸). 一个例子看看现在的java是怎么执行字符串连接操作的.
1.package ch13_String;
2.
3.public class Concatenation {
4. public static void main(String[] args) {
5. String mango ="mango";
6. String s = "abc"+mango+"def"+47;
7. System.out.println(s);
8. }
9.}/*output:
10.Compiled from "Concatenation.java"
11.public class ch13_String.Concatenation {
12. public ch13_String.Concatenation();
13. Code:
14. 0: aload_0
15. 1: invokespecial #8 // Method java/lang/Object."<init>":()V
16. 4: return
17.
18. public static void main(java.lang.String[]);
19. Code:
20. 0: ldc #16 // String mango
21. 2: astore_1
22. 3: new #18 // class java/lang/StringBuilder
23. 6: dup
24. 7: ldc #20 // String abc
25. 9: invokespecial #22 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
26. 12: aload_1
27. 13: invokevirtual #25 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
28. 16: ldc #29 // String def
29. 18: invokevirtual #25 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
30. 21: bipush 47
31. 23: invokevirtual #31 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
32. 26: invokevirtual #34 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
33. 29: astore_2
34. 30: getstatic #38 // Field java/lang/System.out:Ljava/io/PrintStream;
35. 33: aload_2
36. 34: invokevirtual #44 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
37. 37: return
38.}
39.*/
java有一个反编译的工具,可以看到JVM生成的字节码,是一种类似汇编的玩意儿. 当然,现在除了极少数底层程序员之外,很少有人懂汇编了. (这是一件多么悲哀的事情)但是贴心的java给出了一些注释.关于如何在eclipse中使用javap进行反编译,请参考这篇文章(http://blog.csdn.net/ricciozhang/article/details/46994485)
简单来看,实际上,在做字符串连接的时候使用了StringBuider类,并调用StringBuilder类的append方法.这是一种更高效的方法.
也就是说,java其实是对String类型的连接做了优化. 那么这种优化到底有多大的作用呢?
1.package ch13_String;
2.
3.public class WhitherStringBuilder {
4. public String implicit(String[] fileds){
5. String result = "";
6. for(int i =0;i<fileds.length;i++){
7. result+=fileds[i];
8. }
9. return result;
10. }
11. public String explicit(WhitherStringBuilder[] fileds){
12. StringBuilder result = new StringBuilder();
13. for(int i =0;i<fileds.length;i++){
14. result.append(fileds[i]);
15. }
16. return result.toString();
17. }
18.
19.}/*output:
20.Compiled from "WhitherStringBuilder.java"
21.public class ch13_String.WhitherStringBuilder {
22. public ch13_String.WhitherStringBuilder();
23. Code:
24. 0: aload_0
25. 1: invokespecial #8 // Method java/lang/Object."<init>":()V
26. 4: return
27.
28. public java.lang.String implicit(java.lang.String[]);
29. Code:
30. 0: ldc #16 // String
31. 2: astore_2
32. 3: iconst_0
33. 4: istore_3
34. 5: goto 32
35. 8: new #18 // class java/lang/StringBuilder
36. 11: dup
37. 12: aload_2
38. 13: invokestatic #20 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
39. 16: invokespecial #26 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
40. 19: aload_1
41. 20: iload_3
42. 21: aaload
43. 22: invokevirtual #29 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
44. 25: invokevirtual #33 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
45. 28: astore_2
46. 29: iinc 3, 1
47. 32: iload_3
48. 33: aload_1
49. 34: arraylength
50. 35: if_icmplt 8
51. 38: aload_2
52. 39: areturn
53.
54. public java.lang.String explicit(ch13_String.WhitherStringBuilder[]);
55. Code:
56. 0: new #18 // class java/lang/StringBuilder
57. 3: dup
58. 4: invokespecial #46 // Method java/lang/StringBuilder."<init>":()V
59. 7: astore_2
60. 8: iconst_0
61. 9: istore_3
62. 10: goto 24
63. 13: aload_2
64. 14: aload_1
65. 15: iload_3
66. 16: aaload
67. 17: invokevirtual #47 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
68. 20: pop
69. 21: iinc 3, 1
70. 24: iload_3
71. 25: aload_1
72. 26: arraylength
73. 27: if_icmplt 13
74. 30: aload_2
75. 31: invokevirtual #33 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
76. 34: areturn
77.}
78.*/
虽然我是一个不懂汇编的菜鸟,但是单纯从两个方法的注释上就能直观的感觉到,直接使用StringBuilder类的时候,明显方法调用和实例的创建要简洁…实际上是,第一个方法,循环中的每一次都会创建一个StringBuilder类. 显然,这种开销依旧是很大的. 所以说单纯的把String类型的性能优化交给java是不靠谱的.
所以在使用字符串的时候,或者为一个类重写toString()方法的时候,如果字符串操作比较简单,可以相信编译器的优化. 但是如果有频繁的字符串操作,比如有循环的时候,最好自己创建StringBuilder对象.
1.import java.util.Random;
2.
3.public class UsingStringBuilder {
4. Random rand = new Random(47);
5. public String toString(){
6. StringBuilder result = new StringBuilder("[");
7. for(int i=0;i<25;i++){
8. result.append(rand.nextInt(100));
9. result.append(",");
10. }
11. result.delete(result.length()-1, result.length());
12. result.append("]");
13. return result.toString();
14. }
15. public static void main(String[] args) {
16. UsingStringBuilder usb = new UsingStringBuilder();
17. System.out.println(usb);
18. }
19.}
toString()方法的一个坑
toString()方法用于返回一个对象的字符串表示. 如果没有重写的时候,这个方法会返回一个内存标识符的字符串.重写它可以在调用类似 System.out.println()
的时候,得到一个你所期望的字符串的样式.
1.import java.util.ArrayList;
2.import java.util.Random;
3.
4.class Apple{
5. static long counter;
6. static String[] names = {"Fuji","Red delicious","YanTai"};
7. private String name;
8. private long id = counter++;
9. Random rand = new Random();
10. public Apple(){
11. this.name = names[rand.nextInt(3)];
12. }
13. public static ArrayList<Apple> AppleGenerator(int count){
14. ArrayList<Apple> apples = new ArrayList<>();
15. for(int i=0;i<count;i++ ){
16. apples.add(new Apple());
17. }
18. return apples;
19. }
20. public String toString(){
21. return this.name+":"+this.id;
22. }
23.}
24.
25.public class ArrayListDisplay {
26. public static void main(String[] args) {
27. ArrayList<Apple> apples = new ArrayList<>();
28. for(Apple eachApple:Apple.AppleGenerator(10)){
29. apples.add(eachApple);
30. }
31. System.out.println(apples);
32. }
33.}
比如下面这段代码
1.import java.util.ArrayList;
2.import java.util.List;
3.
4.public class InfiniteRecursion {
5. public String toString(){
6.// return "InfiniteRecursion address:"+super.toString()+"\n";
7. return "InfiniteRecursion address:"+this+"\n";
8. }
9. public static void main(String[] args) {
10.// List<InfiniteRecursion> v = new ArrayList<>();
11.// for(int i =0;i<10;i++){
12.// v.add(new InfiniteRecursion());
13.// }
14.// System.out.println(v);
15. InfiniteRecursion infiniteRecursion = new InfiniteRecursion();
16. System.out.println(infiniteRecursion);
17. }
18.}
显然,它是想在toString()方法中返回内存标识符的字符串但是又像加上一些其他的字符串.但是这种调用行不行呢?显然是不行的. 16行打印的时候调用了InfiniteRecursion类的toString方法. 然后在toString方法中,将一个字符串和一个非字符串拼接的时候,那个非字符串类型需要强转. 强转的时候会再次调用该类型下的toString()方法,这时候,会陷入一个无限的迭代中. 埃大爷说会看到一个很长的字符串,但是在javaSE8中是会报错的.所以正确的做法是,调用Object类的toString方法.
String上的操作
String类提供了很多很多很多的方法. 感觉我是记不住的,所以文档里,随用随查吧.
格式化输出
回忆一下C语言,printf(),通过格式修饰符占位的方法进行格式化输出. printf("Row1: [%d %f]",x,y);
javaSE5之后也推出了类似printf()风格的格式化输出.
1.public class SimpleFormat {
2. public static void main(String[] args) {
3. int x =5;
4. double y =2.3333333;
5. System.out.println("Row1: ["+x+ " "+y+"]");
6.
7. System.out.printf("Row1: [%d %f]\n", x,y);
8.
9. System.out.format("Row1: [%d %f]\n", x,y);
10. }
11.}
和C的printf很像.熟悉C的童鞋应该会觉得很亲切. 可是我已经觉得不亲切了…
Formatter类
Formatter是一个printf风格字符串的解释程序,可以用来将格式化的字符串和数据翻译成需要的结果.
1.import java.io.PrintStream;
2.import java.util.Formatter;
3.
4.public class Turtle {
5. private String name;
6. private Formatter f;
7. public Turtle(String name,Formatter f){
8. this.name = name;
9. this.f=f;
10. }
11. public void move(int x,int y){
12. f.format("%s The Turtle is at (%d,%d)\n",name,x,y);
13. }
14. public static void main(String[] args) {
15. PrintStream outAlias = System.out;
16.
17. Turtle tommy = new Turtle("Tommy", new Formatter(outAlias));
18. Turtle terry = new Turtle("Terry", new Formatter(System.out));
19.
20. tommy.move(0, 0);
21. terry.move(4, 8);
22.
23. tommy.move(3, 4);
24. terry.move(2, 5);
25.
26. }
27.}
格式化说明符
格式化说明符的的抽象语法: %[argument_index$][flags][width][.precision]conversion
- width 控制最小宽度,可以用来控制至少达到某个长度
- precision 这个字段用于字符串的时候表示输出字符的最大数量. 用于浮点数的时候,表示显示小数的位数
1.import java.util.Formatter;
2.
3.public class Receipt {
4. private double total =0;
5. private Formatter f = new Formatter(System.out);
6.
7. public void printTitlle(){
8. f.format("%-15s %5s %10s \n", "Item","Qty","Price");
9. f.format("%-15s %5s %10s\n", "----","----","----");
10. }
11.
12. public void print(String name,int qty,double price){
13. f.format("%-15.15s %5d %10.2f\n", name,qty,price);
14. total+=price;
15. }
16.
17. public void printTotal(){
18. f.format("%-15s %5s %10.2f\n", "Tax", "", total*0.06);
19. f.format("%-15s %5s %10s\n", "", "", "-----");
20. f.format("%-15s %5s %10.2f\n", "Total", "", total * 1.06);
21. }
22. public static void main(String[] args) {
23. Receipt receipt = new Receipt();
24. receipt.printTitlle();
25. receipt.print("Jack’s Magic Beans", 4, 4.25);
26. receipt.print("Princess Peas", 3, 5.1);
27. receipt.print("Three Bears Porridge", 1, 14.29);
28. receipt.printTotal();
29. }
30.}/*output:
31.Item Qty Price
32.---- ---- ----
33.Jack’s Magic Be 4 4.25
34.Princess Peas 3 5.10
35.Three Bears Por 1 14.29
36.Tax 1.42
37. -----
38.Total 25.06
39.*/
Formater的转换
Formatter是使用了占位符的,比如%s表示一个String类型. %d表示int类型等等. 如果占位符和实际变量类型对不上的时候会发生什么呢? 答,异常或者强转.
String的format()方法
String下提供了format()方法,可以用于字符串的格式化输出. 其基本使用方法和Formatter.format()一样,只不过返回的是一个String类型. 如果仅仅是需要单次使用format()方法的话String.format()方法会方便很多.
%23%23TJI%u8BFB%u4E66%u7B14%u8BB017-%u5B57%u7B26%u4E32%0A@%28034.java%29%5Bjava%2C%20java%u7F16%u7A0B%u601D%u60F3%5D%0A%0A%5BTOC%5D%0A%0A%0A%u5B57%u7B26%u4E32%u64CD%u4F5C%u53EF%u80FD%u662F%u8BA1%u7B97%u673A%u7A0B%u5E8F%u8BBE%u8BA1%u4E2D%u6700%u5E38%u89C1%u7684%u884C%u4E3A%u4E4B%u4E00.%20%u800C%u6211%u4EEC%u5E38%u89C1%u7684%u5B57%u7B26%u4E32%u7C7B%u578B%u6709String%u7C7B%2CStringBuffer%u7C7B%u548CStringBuilder%u7C7B.%20%u5176%u4E2D%2CString%u7C7B%u578B%u4EE3%u8868%u7684%u662F%u4E00%u4E2A%u4E0D%u53EF%u53D8%u7684%u5B57%u7B26%u4E32%u7C7B%u578B%2C%u800CStringBuffer%u662F%u4E00%u4E2A%u7EBF%u7A0B%u5B89%u5168%u7684%u53EF%u53D8%u5B57%u7B26%u4E32%u5E8F%u5217.%20StringBuilder%u7C7B%u662F%u4E00%u4E2A%u53EF%u53D8%u7684%u5B57%u7B26%u4E32%u5E8F%u5217%2C%u4F46%u662F%u5E76%u4E0D%u662F%u7EBF%u7A0B%u5B89%u5168%u7684%2C%u6027%u80FD%u4E0A%u6BD4StringBuffer%u597D%2C%u53EF%u4EE5%u8BF4%u662F%u5728%u5355%u7EBF%u7A0B%u4E2D%u7684StringBuffer%u7684%u4E00%u4E2A%u7406%u60F3%u4EE3%u66FF.%20%0A%0A%0A%23%23%u4E0D%u53EF%u53D8%u7684String%0AString%u7C7B%u578B%u662F%u4E0D%u53EF%u53D8%u7684.%20String%u7C7B%u578B%u662F%u4E0D%u53EF%u53D8%u7684.%20String%u7C7B%u578B%u662F%u4E0D%u53EF%u53D8%u7684.%20%u6240%u6709%u770B%u4E0A%u53BB%u4FEE%u6539%u4E86String%u7C7B%u578B%u7684%u64CD%u4F5C%u5B9E%u9645%u4E0A%u90FD%u662F%u521B%u5EFA%u4E86%u4E00%u4E2A%u65B0%u7684String%u5B9E%u4F8B.%20%u540C%u65F6String%u7C7B%u578B%u7684equals%u65B9%u6CD5%u4E5F%u88AB%u91CD%u5199%u4E86%2C%u4F7F%u5F97%u5F53String%u7C7B%u578B%u7684%22%u503C%22%u4E00%u6837%u7684%u65F6%u5019%2Cequals%u5224%u65AD%u5C31%u4E3A%u771F.%20%u8FD9%u66F4%u7B26%u5408%u4EBA%u7C7B%u5BF9%u5B57%u7B26%u4E32%u7684%u7406%u89E3.%20%u4F46%u540C%u65F6%u4E5F%u4F1A%u7ED9String%u662F%u4E0D%u53EF%u53D8%u7684%u8FD9%u4E00%u7279%u6027%u7684%u7406%u89E3%u5E26%u6765%u4E00%u5B9A%u7684%u56F0%u6270.%20%0A%60%60%60java%0Apublic%20class%20Immutable%20%7B%0A%09public%20static%20String%20upcase%28String%20s%29%7B%0A%09%09return%20s.toUpperCase%28%29%3B%0A%09%7D%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09String%20str%3D%22hello%22%3B%0A%09%09System.out.println%28str%29%3B%0A%09%09String%20str2%20%3D%20upcase%28str%29%3B%0A%09%09System.out.println%28str2%29%3B%0A%09%7D%0A%7D/*output%3A%0Ahello%0AHELLO%0A*/%0A%60%60%60%0A%u8FD9%u662F%u4E00%u4E2A%u7B80%u5355%u7684%u4F8B%u5B50%2C%u6CA1%u6709%u4EC0%u4E48%u592A%u591A%u597D%u8BF4%u7684.%20%u53EA%u6709%u4E00%u70B9%2Cstr2%u7684%u64CD%u4F5C%2C%u5B9E%u9645%u4E0A%u662F%u5728%u5185%u5B58%u4E2D%u65B0%u5F00%u8F9F%u4E00%u4E2A%u533A%u57DF%2C%u7136%u540E%u5B58%u5165%u8F6C%u6362%u540E%u7684%u5B57%u7B26%u4E32.%20%u7528python%u7684%u8BDD%u8BF4%2C%u8FD9%u4E0D%u662F%u4E00%u4E2A%22%u539F%u5730%u64CD%u4F5C%22.%0A%0A%23%23%u91CD%u8F7D%22+%22%u548CStringBuilder%0Ajava%u662F%u4E0D%u5141%u8BB8%u64CD%u4F5C%u7B26%u91CD%u8F7D%u7684.%20%u4F46%u662Fjava%u7ED9%u4E86%u4E24%u4E2A%u7279%u4F8B%2C%u90A3%u5C31%u662F%u5B57%u7B26%u4E32%u64CD%u4F5C%u4E2D%u7684%22+%22%u548C%22+%3D%22%0A%u9996%u5148%2C%u4E00%u5B9A%u8981%u63A5%u53D7%u4E00%u4E2A%u4E8B%u5B9E%2CString%u7C7B%u578B%u662F%u4E0D%u53EF%u53D8%u7684.%20%u90A3%u4E48%u95EE%u9898%u6765%u4E86%2C%u56E0%u4E3AString%u7C7B%u578B%u662F%u4E0D%u53EF%u53D8%u7684%2C%u90A3%u7531%u6B64%u5E26%u6765%u7684%u6BCF%u6B21String%u76F8%u5173%u7684%u4E00%u4E9B%u64CD%u4F5C%u5728%u6548%u7387%u4E0A%u5C31%u4F1A%u5B58%u5728%u95EE%u9898.%20%u6BD4%u5982%u5B57%u7B26%u4E32%u8FDE%u63A5%60%22hey%22+%22hello%22+%22world%22%60%u8FD9%u4E2A%u64CD%u4F5C%u5E94%u8BE5%u8981%u5982%u4F55%u8FDB%u884C.%20%u5047%u8BBEString%u7C7B%u578B%u6709%u4E2Aappend%28%29%u65B9%u6CD5%2C%u90A3%u4E48%u5148%u521B%u5EFA%u4E00%u4E2A%u5185%u5B58%u533A%u57DF%2C%u5B58%u653E%22hey%22%u548C%22hello%22%u8FDE%u63A5%u540E%u7684%u5B57%u7B26%u4E32%u5047%u8BBE%u53EBstr1%2C%u8FD9%u662F%u4E00%u4E2A%u4E2D%u95F4%u5BF9%u8C61%2C%u7136%u540E%u5728%u6574%u4E00%u4E2A%u65B0%u7684%u5185%u5B58%u533A%u57DF%2C%u5B58%u653Estr1%u548C%22world%22%u8FDE%u63A5%u540E%u7684%u5B57%u7B26%u4E32.%20%20%u5982%u679C%u8BF4%u6709%u5927%u91CF%u7684%u8FD9%u79CD%u5B57%u7B26%u4E32%u8FDE%u63A5%u64CD%u4F5C%2C%u90A3%u4E48%u5C31%u4F1A%u4EA7%u751F%u5927%u91CF%u7684%u4E2D%u95F4%u5BF9%u8C61.%20%u663E%u7136%u8FD9%u79CD%u65B9%u5F0F%u5F00%u9500%u662F%u5F88%u5927%u7684.%20%0A%u90A3%u4E48java%u5B9E%u9645%u4E0A%u662F%u4E0D%u662F%u8FD9%u4E48%u505A%u7684%u5462%3F%u636E%u57C3%u5927%u7237%u8BF4java%u65E9%u671F%u771F%u7684%u662F%u8FD9%u4E48%u505A%u7684.%28%u6211%u5E74%u7EAA%u5C0F%2C%u6CA1%u6709%u7ECF%u5386%u8FC7%u8FD9%u4E9B%2C%u6342%u8138%29.%20%u4E00%u4E2A%u4F8B%u5B50%u770B%u770B%u73B0%u5728%u7684java%u662F%u600E%u4E48%u6267%u884C%u5B57%u7B26%u4E32%u8FDE%u63A5%u64CD%u4F5C%u7684.%20%0A%60%60%60java%0Apackage%20ch13_String%3B%0A%0Apublic%20class%20Concatenation%20%7B%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09String%20mango%20%3D%22mango%22%3B%0A%09%09String%20s%20%3D%20%22abc%22+mango+%22def%22+47%3B%0A%09%09System.out.println%28s%29%3B%0A%09%7D%0A%7D/*output%3A%0ACompiled%20from%20%22Concatenation.java%22%0Apublic%20class%20ch13_String.Concatenation%20%7B%0A%20%20public%20ch13_String.Concatenation%28%29%3B%0A%20%20%20%20Code%3A%0A%20%20%20%20%20%20%200%3A%20aload_0%0A%20%20%20%20%20%20%201%3A%20invokespecial%20%238%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/Object.%22%3Cinit%3E%22%3A%28%29V%0A%20%20%20%20%20%20%204%3A%20return%0A%0A%20%20public%20static%20void%20main%28java.lang.String%5B%5D%29%3B%0A%20%20%20%20Code%3A%0A%20%20%20%20%20%20%200%3A%20ldc%20%20%20%20%20%20%20%20%20%20%20%2316%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20String%20mango%0A%20%20%20%20%20%20%202%3A%20astore_1%0A%20%20%20%20%20%20%203%3A%20new%20%20%20%20%20%20%20%20%20%20%20%2318%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20class%20java/lang/StringBuilder%0A%20%20%20%20%20%20%206%3A%20dup%0A%20%20%20%20%20%20%207%3A%20ldc%20%20%20%20%20%20%20%20%20%20%20%2320%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20String%20abc%0A%20%20%20%20%20%20%209%3A%20invokespecial%20%2322%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/StringBuilder.%22%3Cinit%3E%22%3A%28Ljava/lang/String%3B%29V%0A%20%20%20%20%20%2012%3A%20aload_1%0A%20%20%20%20%20%2013%3A%20invokevirtual%20%2325%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/StringBuilder.append%3A%28Ljava/lang/String%3B%29Ljava/lang/StringBuilder%3B%0A%20%20%20%20%20%2016%3A%20ldc%20%20%20%20%20%20%20%20%20%20%20%2329%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20String%20def%0A%20%20%20%20%20%2018%3A%20invokevirtual%20%2325%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/StringBuilder.append%3A%28Ljava/lang/String%3B%29Ljava/lang/StringBuilder%3B%0A%20%20%20%20%20%2021%3A%20bipush%20%20%20%20%20%20%20%2047%0A%20%20%20%20%20%2023%3A%20invokevirtual%20%2331%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/StringBuilder.append%3A%28I%29Ljava/lang/StringBuilder%3B%0A%20%20%20%20%20%2026%3A%20invokevirtual%20%2334%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/StringBuilder.toString%3A%28%29Ljava/lang/String%3B%0A%20%20%20%20%20%2029%3A%20astore_2%0A%20%20%20%20%20%2030%3A%20getstatic%20%20%20%20%20%2338%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Field%20java/lang/System.out%3ALjava/io/PrintStream%3B%0A%20%20%20%20%20%2033%3A%20aload_2%0A%20%20%20%20%20%2034%3A%20invokevirtual%20%2344%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/io/PrintStream.println%3A%28Ljava/lang/String%3B%29V%0A%20%20%20%20%20%2037%3A%20return%0A%7D%0A*/%0A%60%60%60%0Ajava%u6709%u4E00%u4E2A%u53CD%u7F16%u8BD1%u7684%u5DE5%u5177%2C%u53EF%u4EE5%u770B%u5230JVM%u751F%u6210%u7684%u5B57%u8282%u7801%2C%u662F%u4E00%u79CD%u7C7B%u4F3C%u6C47%u7F16%u7684%u73A9%u610F%u513F.%20%u5F53%u7136%2C%u73B0%u5728%u9664%u4E86%u6781%u5C11%u6570%u5E95%u5C42%u7A0B%u5E8F%u5458%u4E4B%u5916%2C%u5F88%u5C11%u6709%u4EBA%u61C2%u6C47%u7F16%u4E86.%20%28%u8FD9%u662F%u4E00%u4EF6%u591A%u4E48%u60B2%u54C0%u7684%u4E8B%u60C5%29%u4F46%u662F%u8D34%u5FC3%u7684java%u7ED9%u51FA%u4E86%u4E00%u4E9B%u6CE8%u91CA.%u5173%u4E8E%u5982%u4F55%u5728eclipse%u4E2D%u4F7F%u7528javap%u8FDB%u884C%u53CD%u7F16%u8BD1%2C%u8BF7%u53C2%u8003%u8FD9%u7BC7%u6587%u7AE0%28http%3A//blog.csdn.net/ricciozhang/article/details/46994485%29%0A%u7B80%u5355%u6765%u770B%2C%u5B9E%u9645%u4E0A%2C%u5728%u505A%u5B57%u7B26%u4E32%u8FDE%u63A5%u7684%u65F6%u5019%u4F7F%u7528%u4E86StringBuider%u7C7B%2C%u5E76%u8C03%u7528StringBuilder%u7C7B%u7684append%u65B9%u6CD5.%u8FD9%u662F%u4E00%u79CD%u66F4%u9AD8%u6548%u7684%u65B9%u6CD5.%20%0A%u4E5F%u5C31%u662F%u8BF4%2Cjava%u5176%u5B9E%u662F%u5BF9String%u7C7B%u578B%u7684%u8FDE%u63A5%u505A%u4E86%u4F18%u5316.%20%u90A3%u4E48%u8FD9%u79CD%u4F18%u5316%u5230%u5E95%u6709%u591A%u5927%u7684%u4F5C%u7528%u5462%3F%0A%0A%60%60%60java%0Apackage%20ch13_String%3B%0A%0Apublic%20class%20WhitherStringBuilder%20%7B%0A%09public%20String%20implicit%28String%5B%5D%20fileds%29%7B%0A%09%09String%20result%20%3D%20%22%22%3B%0A%09%09for%28int%20i%20%3D0%3Bi%3Cfileds.length%3Bi++%29%7B%0A%09%09%09result+%3Dfileds%5Bi%5D%3B%0A%09%09%7D%0A%09%09return%20result%3B%0A%09%7D%0A%09public%20String%20explicit%28WhitherStringBuilder%5B%5D%20fileds%29%7B%0A%09%09StringBuilder%20result%20%3D%20new%20StringBuilder%28%29%3B%0A%09%09for%28int%20i%20%3D0%3Bi%3Cfileds.length%3Bi++%29%7B%0A%09%09%09result.append%28fileds%5Bi%5D%29%3B%0A%09%09%7D%0A%09%09return%20result.toString%28%29%3B%0A%09%7D%0A%09%0A%7D/*output%3A%0ACompiled%20from%20%22WhitherStringBuilder.java%22%0Apublic%20class%20ch13_String.WhitherStringBuilder%20%7B%0A%20%20public%20ch13_String.WhitherStringBuilder%28%29%3B%0A%20%20%20%20Code%3A%0A%20%20%20%20%20%20%200%3A%20aload_0%0A%20%20%20%20%20%20%201%3A%20invokespecial%20%238%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/Object.%22%3Cinit%3E%22%3A%28%29V%0A%20%20%20%20%20%20%204%3A%20return%0A%0A%20%20public%20java.lang.String%20implicit%28java.lang.String%5B%5D%29%3B%0A%20%20%20%20Code%3A%0A%20%20%20%20%20%20%200%3A%20ldc%20%20%20%20%20%20%20%20%20%20%20%2316%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20String%0A%20%20%20%20%20%20%202%3A%20astore_2%0A%20%20%20%20%20%20%203%3A%20iconst_0%0A%20%20%20%20%20%20%204%3A%20istore_3%0A%20%20%20%20%20%20%205%3A%20goto%20%20%20%20%20%20%20%20%20%2032%0A%20%20%20%20%20%20%208%3A%20new%20%20%20%20%20%20%20%20%20%20%20%2318%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20class%20java/lang/StringBuilder%0A%20%20%20%20%20%2011%3A%20dup%0A%20%20%20%20%20%2012%3A%20aload_2%0A%20%20%20%20%20%2013%3A%20invokestatic%20%20%2320%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/String.valueOf%3A%28Ljava/lang/Object%3B%29Ljava/lang/String%3B%0A%20%20%20%20%20%2016%3A%20invokespecial%20%2326%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/StringBuilder.%22%3Cinit%3E%22%3A%28Ljava/lang/String%3B%29V%0A%20%20%20%20%20%2019%3A%20aload_1%0A%20%20%20%20%20%2020%3A%20iload_3%0A%20%20%20%20%20%2021%3A%20aaload%0A%20%20%20%20%20%2022%3A%20invokevirtual%20%2329%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/StringBuilder.append%3A%28Ljava/lang/String%3B%29Ljava/lang/StringBuilder%3B%0A%20%20%20%20%20%2025%3A%20invokevirtual%20%2333%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/StringBuilder.toString%3A%28%29Ljava/lang/String%3B%0A%20%20%20%20%20%2028%3A%20astore_2%0A%20%20%20%20%20%2029%3A%20iinc%20%20%20%20%20%20%20%20%20%203%2C%201%0A%20%20%20%20%20%2032%3A%20iload_3%0A%20%20%20%20%20%2033%3A%20aload_1%0A%20%20%20%20%20%2034%3A%20arraylength%0A%20%20%20%20%20%2035%3A%20if_icmplt%20%20%20%20%208%0A%20%20%20%20%20%2038%3A%20aload_2%0A%20%20%20%20%20%2039%3A%20areturn%0A%0A%20%20public%20java.lang.String%20explicit%28ch13_String.WhitherStringBuilder%5B%5D%29%3B%0A%20%20%20%20Code%3A%0A%20%20%20%20%20%20%200%3A%20new%20%20%20%20%20%20%20%20%20%20%20%2318%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20class%20java/lang/StringBuilder%0A%20%20%20%20%20%20%203%3A%20dup%0A%20%20%20%20%20%20%204%3A%20invokespecial%20%2346%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/StringBuilder.%22%3Cinit%3E%22%3A%28%29V%0A%20%20%20%20%20%20%207%3A%20astore_2%0A%20%20%20%20%20%20%208%3A%20iconst_0%0A%20%20%20%20%20%20%209%3A%20istore_3%0A%20%20%20%20%20%2010%3A%20goto%20%20%20%20%20%20%20%20%20%2024%0A%20%20%20%20%20%2013%3A%20aload_2%0A%20%20%20%20%20%2014%3A%20aload_1%0A%20%20%20%20%20%2015%3A%20iload_3%0A%20%20%20%20%20%2016%3A%20aaload%0A%20%20%20%20%20%2017%3A%20invokevirtual%20%2347%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/StringBuilder.append%3A%28Ljava/lang/Object%3B%29Ljava/lang/StringBuilder%3B%0A%20%20%20%20%20%2020%3A%20pop%0A%20%20%20%20%20%2021%3A%20iinc%20%20%20%20%20%20%20%20%20%203%2C%201%0A%20%20%20%20%20%2024%3A%20iload_3%0A%20%20%20%20%20%2025%3A%20aload_1%0A%20%20%20%20%20%2026%3A%20arraylength%0A%20%20%20%20%20%2027%3A%20if_icmplt%20%20%20%20%2013%0A%20%20%20%20%20%2030%3A%20aload_2%0A%20%20%20%20%20%2031%3A%20invokevirtual%20%2333%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20Method%20java/lang/StringBuilder.toString%3A%28%29Ljava/lang/String%3B%0A%20%20%20%20%20%2034%3A%20areturn%0A%7D%0A*/%0A%60%60%60%20%0A%0A%u867D%u7136%u6211%u662F%u4E00%u4E2A%u4E0D%u61C2%u6C47%u7F16%u7684%u83DC%u9E1F%2C%u4F46%u662F%u5355%u7EAF%u4ECE%u4E24%u4E2A%u65B9%u6CD5%u7684%u6CE8%u91CA%u4E0A%u5C31%u80FD%u76F4%u89C2%u7684%u611F%u89C9%u5230%2C%u76F4%u63A5%u4F7F%u7528StringBuilder%u7C7B%u7684%u65F6%u5019%2C%u660E%u663E%u65B9%u6CD5%u8C03%u7528%u548C%u5B9E%u4F8B%u7684%u521B%u5EFA%u8981%u7B80%u6D01...%u5B9E%u9645%u4E0A%u662F%2C%u7B2C%u4E00%u4E2A%u65B9%u6CD5%2C%u5FAA%u73AF%u4E2D%u7684%u6BCF%u4E00%u6B21%u90FD%u4F1A%u521B%u5EFA%u4E00%u4E2AStringBuilder%u7C7B.%20%u663E%u7136%2C%u8FD9%u79CD%u5F00%u9500%u4F9D%u65E7%u662F%u5F88%u5927%u7684.%20%u6240%u4EE5%u8BF4%u5355%u7EAF%u7684%u628AString%u7C7B%u578B%u7684%u6027%u80FD%u4F18%u5316%u4EA4%u7ED9java%u662F%u4E0D%u9760%u8C31%u7684.%20%0A%20%0A%20%0A%u6240%u4EE5%u5728%u4F7F%u7528%u5B57%u7B26%u4E32%u7684%u65F6%u5019%2C%u6216%u8005%u4E3A%u4E00%u4E2A%u7C7B%u91CD%u5199toString%28%29%u65B9%u6CD5%u7684%u65F6%u5019%2C%u5982%u679C%u5B57%u7B26%u4E32%u64CD%u4F5C%u6BD4%u8F83%u7B80%u5355%2C%u53EF%u4EE5%u76F8%u4FE1%u7F16%u8BD1%u5668%u7684%u4F18%u5316.%20%u4F46%u662F%u5982%u679C%u6709%u9891%u7E41%u7684%u5B57%u7B26%u4E32%u64CD%u4F5C%2C%u6BD4%u5982%u6709%u5FAA%u73AF%u7684%u65F6%u5019%2C%u6700%u597D%u81EA%u5DF1%u521B%u5EFAStringBuilder%u5BF9%u8C61.%0A%60%60%60java%0Aimport%20java.util.Random%3B%0A%0Apublic%20class%20UsingStringBuilder%20%7B%0A%09Random%20rand%20%3D%20new%20Random%2847%29%3B%0A%09public%20String%20toString%28%29%7B%0A%09%09StringBuilder%20result%20%3D%20new%20StringBuilder%28%22%5B%22%29%3B%0A%09%09for%28int%20i%3D0%3Bi%3C25%3Bi++%29%7B%0A%09%09%09result.append%28rand.nextInt%28100%29%29%3B%0A%09%09%09result.append%28%22%2C%22%29%3B%0A%09%09%7D%0A%09%09result.delete%28result.length%28%29-1%2C%20result.length%28%29%29%3B%0A%09%09result.append%28%22%5D%22%29%3B%0A%09%09return%20result.toString%28%29%3B%0A%09%7D%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09UsingStringBuilder%20usb%20%3D%20new%20UsingStringBuilder%28%29%3B%0A%09%09System.out.println%28usb%29%3B%0A%09%7D%0A%7D%0A%60%60%60%0A%0A%23%23toString%28%29%u65B9%u6CD5%u7684%u4E00%u4E2A%u5751%0AtoString%28%29%u65B9%u6CD5%u7528%u4E8E%u8FD4%u56DE%u4E00%u4E2A%u5BF9%u8C61%u7684%u5B57%u7B26%u4E32%u8868%u793A.%20%u5982%u679C%u6CA1%u6709%u91CD%u5199%u7684%u65F6%u5019%2C%u8FD9%u4E2A%u65B9%u6CD5%u4F1A%u8FD4%u56DE%u4E00%u4E2A%u5185%u5B58%u6807%u8BC6%u7B26%u7684%u5B57%u7B26%u4E32.%u91CD%u5199%u5B83%u53EF%u4EE5%u5728%u8C03%u7528%u7C7B%u4F3C%20%60%20System.out.println%28%29%60%u7684%u65F6%u5019%2C%u5F97%u5230%u4E00%u4E2A%u4F60%u6240%u671F%u671B%u7684%u5B57%u7B26%u4E32%u7684%u6837%u5F0F.%20%0A%60%60%60java%0Aimport%20java.util.ArrayList%3B%0Aimport%20java.util.Random%3B%0A%0Aclass%20Apple%7B%0A%09static%20long%20counter%3B%0A%09static%20String%5B%5D%20names%20%3D%20%7B%22Fuji%22%2C%22Red%20delicious%22%2C%22YanTai%22%7D%3B%0A%09private%20String%20name%3B%0A%09private%20long%20id%20%3D%20counter++%3B%0A%09Random%20rand%20%3D%20new%20Random%28%29%3B%0A%09public%20Apple%28%29%7B%0A%09%09this.name%20%3D%20names%5Brand.nextInt%283%29%5D%3B%0A%09%7D%0A%09public%20static%20ArrayList%3CApple%3E%20AppleGenerator%28int%20count%29%7B%0A%09%09ArrayList%3CApple%3E%20apples%20%3D%20new%20ArrayList%3C%3E%28%29%3B%0A%09%09for%28int%20i%3D0%3Bi%3Ccount%3Bi++%20%29%7B%0A%09%09%09apples.add%28new%20Apple%28%29%29%3B%0A%09%09%7D%0A%09%09return%20apples%3B%0A%09%7D%0A%09public%20String%20toString%28%29%7B%0A%09%09return%20this.name+%22%3A%22+this.id%3B%0A%09%7D%0A%7D%0A%0Apublic%20class%20ArrayListDisplay%20%7B%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09ArrayList%3CApple%3E%20apples%20%3D%20new%20ArrayList%3C%3E%28%29%3B%0A%09%09for%28Apple%20eachApple%3AApple.AppleGenerator%2810%29%29%7B%0A%09%09%09apples.add%28eachApple%29%3B%0A%09%09%7D%0A%09%09System.out.println%28apples%29%3B%0A%09%7D%0A%7D%0A%60%60%60%0A%0A%u6BD4%u5982%u4E0B%u9762%u8FD9%u6BB5%u4EE3%u7801%0A%60%60%60java%0Aimport%20java.util.ArrayList%3B%0Aimport%20java.util.List%3B%0A%0Apublic%20class%20InfiniteRecursion%20%7B%0A%09public%20String%20toString%28%29%7B%0A//%09%09return%20%22InfiniteRecursion%20address%3A%22+super.toString%28%29+%22%5Cn%22%3B%0A%09%09return%20%22InfiniteRecursion%20address%3A%22+this+%22%5Cn%22%3B%0A%09%7D%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A//%09%09List%3CInfiniteRecursion%3E%20v%20%3D%20new%20ArrayList%3C%3E%28%29%3B%0A//%09%09for%28int%20i%20%3D0%3Bi%3C10%3Bi++%29%7B%0A//%09%09%09v.add%28new%20InfiniteRecursion%28%29%29%3B%0A//%09%09%7D%0A//%09%09System.out.println%28v%29%3B%0A%09%09InfiniteRecursion%20infiniteRecursion%20%3D%20new%20InfiniteRecursion%28%29%3B%0A%09%09System.out.println%28infiniteRecursion%29%3B%0A%09%7D%0A%7D%0A%60%60%60%0A%u663E%u7136%2C%u5B83%u662F%u60F3%u5728toString%28%29%u65B9%u6CD5%u4E2D%u8FD4%u56DE%u5185%u5B58%u6807%u8BC6%u7B26%u7684%u5B57%u7B26%u4E32%u4F46%u662F%u53C8%u50CF%u52A0%u4E0A%u4E00%u4E9B%u5176%u4ED6%u7684%u5B57%u7B26%u4E32.%u4F46%u662F%u8FD9%u79CD%u8C03%u7528%u884C%u4E0D%u884C%u5462%3F%u663E%u7136%u662F%u4E0D%u884C%u7684.%2016%u884C%u6253%u5370%u7684%u65F6%u5019%u8C03%u7528%u4E86InfiniteRecursion%u7C7B%u7684toString%u65B9%u6CD5.%20%u7136%u540E%u5728toString%u65B9%u6CD5%u4E2D%2C%u5C06%u4E00%u4E2A%u5B57%u7B26%u4E32%u548C%u4E00%u4E2A%u975E%u5B57%u7B26%u4E32%u62FC%u63A5%u7684%u65F6%u5019%2C%u90A3%u4E2A%u975E%u5B57%u7B26%u4E32%u7C7B%u578B%u9700%u8981%u5F3A%u8F6C.%20%u5F3A%u8F6C%u7684%u65F6%u5019%u4F1A%u518D%u6B21%u8C03%u7528%u8BE5%u7C7B%u578B%u4E0B%u7684toString%28%29%u65B9%u6CD5%2C%u8FD9%u65F6%u5019%2C%u4F1A%u9677%u5165%u4E00%u4E2A%u65E0%u9650%u7684%u8FED%u4EE3%u4E2D.%20%20%u57C3%u5927%u7237%u8BF4%u4F1A%u770B%u5230%u4E00%u4E2A%u5F88%u957F%u7684%u5B57%u7B26%u4E32%2C%u4F46%u662F%u5728javaSE8%u4E2D%u662F%u4F1A%u62A5%u9519%u7684.%u6240%u4EE5%u6B63%u786E%u7684%u505A%u6CD5%u662F%2C%u8C03%u7528Object%u7C7B%u7684toString%u65B9%u6CD5.%20%0A%0A%23%23String%u4E0A%u7684%u64CD%u4F5C%0AString%u7C7B%u63D0%u4F9B%u4E86%u5F88%u591A%u5F88%u591A%u5F88%u591A%u7684%u65B9%u6CD5.%20%u611F%u89C9%u6211%u662F%u8BB0%u4E0D%u4F4F%u7684%2C%u6240%u4EE5%u6587%u6863%u91CC%2C%u968F%u7528%u968F%u67E5%u5427.%20%0A%0A%23%23%u683C%u5F0F%u5316%u8F93%u51FA%0A%u56DE%u5FC6%u4E00%u4E0BC%u8BED%u8A00%2Cprintf%28%29%2C%u901A%u8FC7%u683C%u5F0F%u4FEE%u9970%u7B26%u5360%u4F4D%u7684%u65B9%u6CD5%u8FDB%u884C%u683C%u5F0F%u5316%u8F93%u51FA.%20%0A%60printf%28%22Row1%3A%20%5B%25d%20%25f%5D%22%2Cx%2Cy%29%3B%60%0A%0AjavaSE5%u4E4B%u540E%u4E5F%u63A8%u51FA%u4E86%u7C7B%u4F3Cprintf%28%29%u98CE%u683C%u7684%u683C%u5F0F%u5316%u8F93%u51FA.%20%0A%0A%60%60%60java%0Apublic%20class%20SimpleFormat%20%7B%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09int%20x%20%3D5%3B%0A%09%09double%20y%20%3D2.3333333%3B%0A%09%09System.out.println%28%22Row1%3A%20%5B%22+x+%20%22%20%22+y+%22%5D%22%29%3B%0A%09%09%0A%09%09System.out.printf%28%22Row1%3A%20%5B%25d%20%25f%5D%5Cn%22%2C%20x%2Cy%29%3B%0A%09%09%0A%09%09System.out.format%28%22Row1%3A%20%5B%25d%20%25f%5D%5Cn%22%2C%20x%2Cy%29%3B%0A%09%7D%0A%7D%0A%60%60%60%20%0A%u548CC%u7684printf%u5F88%u50CF.%u719F%u6089C%u7684%u7AE5%u978B%u5E94%u8BE5%u4F1A%u89C9%u5F97%u5F88%u4EB2%u5207.%20%u53EF%u662F%u6211%u5DF2%u7ECF%u89C9%u5F97%u4E0D%u4EB2%u5207%u4E86...%0A%0A%23%23%23Formatter%u7C7B%0AFormatter%u662F%u4E00%u4E2Aprintf%u98CE%u683C%u5B57%u7B26%u4E32%u7684%u89E3%u91CA%u7A0B%u5E8F%2C%u53EF%u4EE5%u7528%u6765%u5C06%u683C%u5F0F%u5316%u7684%u5B57%u7B26%u4E32%u548C%u6570%u636E%u7FFB%u8BD1%u6210%u9700%u8981%u7684%u7ED3%u679C.%20%0A%60%60%60java%0Aimport%20java.io.PrintStream%3B%0Aimport%20java.util.Formatter%3B%0A%0Apublic%20class%20Turtle%20%7B%0A%09private%20String%20name%3B%0A%09private%20Formatter%20f%3B%0A%09public%20Turtle%28String%20name%2CFormatter%20f%29%7B%0A%09%09this.name%20%3D%20name%3B%0A%09%09this.f%3Df%3B%0A%09%7D%0A%09public%20void%20move%28int%20x%2Cint%20y%29%7B%0A%09%09f.format%28%22%25s%20The%20Turtle%20is%20at%20%28%25d%2C%25d%29%5Cn%22%2Cname%2Cx%2Cy%29%3B%0A%09%7D%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09PrintStream%20outAlias%20%3D%20System.out%3B%0A%09%09%0A%09%09Turtle%20tommy%20%3D%20new%20Turtle%28%22Tommy%22%2C%20new%20Formatter%28outAlias%29%29%3B%0A%09%09Turtle%20terry%20%3D%20new%20Turtle%28%22Terry%22%2C%20new%20Formatter%28System.out%29%29%3B%0A%09%09%0A%09%09tommy.move%280%2C%200%29%3B%0A%09%09terry.move%284%2C%208%29%3B%0A%09%09%0A%09%09tommy.move%283%2C%204%29%3B%0A%09%09terry.move%282%2C%205%29%3B%0A%09%09%09%09%0A%09%7D%0A%7D%0A%60%60%60%0A%0A**%u683C%u5F0F%u5316%u8BF4%u660E%u7B26**%0A%u683C%u5F0F%u5316%u8BF4%u660E%u7B26%u7684%u7684%u62BD%u8C61%u8BED%u6CD5%3A%0A%60%25%5Bargument_index%24%5D%5Bflags%5D%5Bwidth%5D%5B.precision%5Dconversion%60%0A%0A-%20width%20%u63A7%u5236%u6700%u5C0F%u5BBD%u5EA6%2C%u53EF%u4EE5%u7528%u6765%u63A7%u5236%u81F3%u5C11%u8FBE%u5230%u67D0%u4E2A%u957F%u5EA6%0A-%20precision%20%u8FD9%u4E2A%u5B57%u6BB5%u7528%u4E8E%u5B57%u7B26%u4E32%u7684%u65F6%u5019%u8868%u793A%u8F93%u51FA%u5B57%u7B26%u7684%u6700%u5927%u6570%u91CF.%20%u7528%u4E8E%u6D6E%u70B9%u6570%u7684%u65F6%u5019%2C%u8868%u793A%u663E%u793A%u5C0F%u6570%u7684%u4F4D%u6570%0A%0A%60%60%60java%0Aimport%20java.util.Formatter%3B%0A%0Apublic%20class%20Receipt%20%7B%0A%09private%20double%20total%20%3D0%3B%0A%09private%20Formatter%20f%20%3D%20new%20Formatter%28System.out%29%3B%0A%09%0A%09public%20void%20printTitlle%28%29%7B%0A%09%09f.format%28%22%25-15s%20%255s%20%2510s%20%5Cn%22%2C%20%22Item%22%2C%22Qty%22%2C%22Price%22%29%3B%0A%09%09f.format%28%22%25-15s%20%255s%20%2510s%5Cn%22%2C%20%22----%22%2C%22----%22%2C%22----%22%29%3B%0A%09%7D%0A%09%0A%09public%20void%20print%28String%20name%2Cint%20qty%2Cdouble%20price%29%7B%0A%09%09f.format%28%22%25-15.15s%20%255d%20%2510.2f%5Cn%22%2C%20name%2Cqty%2Cprice%29%3B%0A%09%09total+%3Dprice%3B%0A%09%7D%0A%09%0A%09public%20void%20printTotal%28%29%7B%0A%09%09%20f.format%28%22%25-15s%20%255s%20%2510.2f%5Cn%22%2C%20%22Tax%22%2C%20%22%22%2C%20total*0.06%29%3B%20%0A%09%09%20f.format%28%22%25-15s%20%255s%20%2510s%5Cn%22%2C%20%22%22%2C%20%22%22%2C%20%22-----%22%29%3B%20%0A%09%09%20f.format%28%22%25-15s%20%255s%20%2510.2f%5Cn%22%2C%20%22Total%22%2C%20%22%22%2C%20total%20*%201.06%29%3B%0A%09%7D%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09Receipt%20receipt%20%3D%20new%20Receipt%28%29%3B%0A%09%09receipt.printTitlle%28%29%3B%0A%09%09receipt.print%28%22Jack%u2019s%20Magic%20Beans%22%2C%204%2C%204.25%29%3B%20%0A%09%20%20%20%20receipt.print%28%22Princess%20Peas%22%2C%203%2C%205.1%29%3B%20%0A%09%20%20%20%20receipt.print%28%22Three%20Bears%20Porridge%22%2C%201%2C%2014.29%29%3B%20%0A%09%20%20%20%20receipt.printTotal%28%29%3B%0A%09%7D%0A%7D/*output%3A%0AItem%20%20%20%20%20%20%20%20%20%20%20%20%20%20Qty%20%20%20%20%20%20Price%20%0A----%20%20%20%20%20%20%20%20%20%20%20%20%20----%20%20%20%20%20%20%20----%0AJack%u2019s%20Magic%20Be%20%20%20%20%204%20%20%20%20%20%20%204.25%0APrincess%20Peas%20%20%20%20%20%20%203%20%20%20%20%20%20%205.10%0AThree%20Bears%20Por%20%20%20%20%201%20%20%20%20%20%2014.29%0ATax%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%201.42%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20-----%0ATotal%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2025.06%0A*/%0A%60%60%60%0A%0A**Formater%u7684%u8F6C%u6362**%0AFormatter%u662F%u4F7F%u7528%u4E86%u5360%u4F4D%u7B26%u7684%2C%u6BD4%u5982%25s%u8868%u793A%u4E00%u4E2AString%u7C7B%u578B.%20%25d%u8868%u793Aint%u7C7B%u578B%u7B49%u7B49.%20%u5982%u679C%u5360%u4F4D%u7B26%u548C%u5B9E%u9645%u53D8%u91CF%u7C7B%u578B%u5BF9%u4E0D%u4E0A%u7684%u65F6%u5019%u4F1A%u53D1%u751F%u4EC0%u4E48%u5462%3F%20%u7B54%2C%u5F02%u5E38%u6216%u8005%u5F3A%u8F6C.%0A%21%5BAlt%20text%5D%28./1475157471249.png%29%0A%0A**String%u7684format%28%29%u65B9%u6CD5**%0AString%u4E0B%u63D0%u4F9B%u4E86format%28%29%u65B9%u6CD5%2C%u53EF%u4EE5%u7528%u4E8E%u5B57%u7B26%u4E32%u7684%u683C%u5F0F%u5316%u8F93%u51FA.%20%u5176%u57FA%u672C%u4F7F%u7528%u65B9%u6CD5%u548CFormatter.format%28%29%u4E00%u6837%2C%u53EA%u4E0D%u8FC7%u8FD4%u56DE%u7684%u662F%u4E00%u4E2AString%u7C7B%u578B.%20%u5982%u679C%u4EC5%u4EC5%u662F%u9700%u8981%u5355%u6B21%u4F7F%u7528format%28%29%u65B9%u6CD5%u7684%u8BDDString.format%28%29%u65B9%u6CD5%u4F1A%u65B9%u4FBF%u5F88%u591A.%20%0A%0A%0A