2012-05-04 36 views
5

Tôi đã thảo luận về cách sử dụng String s và StringBuffer s trong Java. Có bao nhiêu đối tượng được tạo ra trong mỗi hai ví dụ này?Có bao nhiêu đối tượng được tạo

Ex 1:

String s = "a"; 
s = s + "b"; 
s = s + "c";   

Ex 2:

StringBuilder sb = new StringBuilder("a"); 
sb.append("b"); 
sb.append("c"); 

Theo tôi, Ex 1 sẽ tạo ra 5 và Ex 2 sẽ tạo ra 4 đối tượng.

+2

Ví dụ đầu tiên sẽ tạo 1 đối tượng khi trình biên dịch có thể tối ưu hóa nó. –

+0

javac sẽ tối ưu hóa điều đó? –

+1

Ví dụ 1 tạo ra điều này: 'String s =" a "; s = (StringBuilder mới (String.valueOf (s))). Chắp thêm ("b"). ToString(); s = (StringBuilder mới (String.valueOf (s))). Chắp thêm ("c"). ToString(); System.err.println (s); '. Có vẻ như javac không tối ưu hóa (ít nhất là trong Java 6) –

Trả lời

4

Bạn có thể xác định câu trả lời bằng cách phân tích bytecode java (sử dụng javap -c). Ví dụ 1 tạo hai đối tượng StringBuilder (xem dòng # 4) và hai đối tượng String (xem dòng # 7), trong khi ví dụ 2 tạo một đối tượng StringBuilder (xem dòng # 2).

Lưu ý rằng bạn cũng phải xem các đối tượng char[] (vì mảng là đối tượng trong Java). StringStringBuilder đối tượng đều được triển khai bằng cách sử dụng một số cơ bản char[]. Do đó, ví dụ 1 tạo ra các đối tượng tám và ví dụ 2 tạo ra hai đối tượng.

Ví dụ 1:

public static void main(java.lang.String[]); 
    Code: 
    0: ldc    #2; //String a 
    2: astore_1 
    3: new    #3; //class java/lang/StringBuilder 
    6: dup 
    7: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V 
    10: aload_1 
    11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    14: ldc    #6; //String b 
    16: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    19: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    22: astore_1 
    23: new    #3; //class java/lang/StringBuilder 
    26: dup 
    27: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V 
    30: aload_1 
    31: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    34: ldc    #8; //String c 
    36: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    39: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    42: astore_1 
    43: return 
} 

Ví dụ 2:

public static void main(java.lang.String[]); 
    Code: 
    0: new    #2; //class java/lang/StringBuilder 
    3: dup 
    4: ldc    #3; //String a 
    6: invokespecial #4; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    9: astore_1 
    10: aload_1 
    11: ldc    #5; //String b 
    13: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    16: pop 
    17: aload_1 
    18: ldc    #7; //String c 
    20: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    23: pop 
    24: return 
} 
+0

Tôi có một chút nghi ngờ. , tài liệu oracle tại đây http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html nói điều này về nối thêm: "công cộng StringBuilder nối thêm (Object obj) Gắn thêm biểu diễn chuỗi của Đối số đối tượng Hiệu ứng tổng thể là chính xác như đối số được chuyển đổi thành chuỗi bằng phương thức String.valueOf (Object), và các ký tự của chuỗi đó sau đó được nối thêm vào chuỗi ký tự này. " Điều đó không có nghĩa là các đối tượng sẽ được tạo cho các chuỗi ký tự. –

5

Xét về đối tượng được tạo:

Ví dụ 1 tạo ra 8 đối tượng:

String s = "a"; // No object created 
s = s + "b"; // 1 StringBuilder/StringBuffer + 1 String + 2 char[] (1 for SB and 1 for String) 
s = s + "c"; // 1 StringBuilder/StringBuffer + 1 String + 2 char[] (1 for SB and 1 for String) 

Ví dụ 2 tạo ra 2 đối tượng:

StringBuffer sb = new StringBuffer("a"); // 1 StringBuffer + 1 char[] (in SB) 
sb.append("b"); // 0 
sb.append("c"); // 0 

Để công bằng, tôi đã không biết rằng mới char [] thực sự đã tạo ra một đối tượng trong Java (nhưng tôi biết chúng đã được tạo ra). Nhờ aix đã chỉ ra điều đó.

+0

Downvoter bạn sẽ quan tâm để cung cấp ý kiến ​​của bạn? –

+0

Người đó có thể chạy thủ tục kiểm tra trong một phiên bản JDK khác và thu được các kết quả khác nhau. –

5

Tôi đã sử dụng một hồ sơ bộ nhớ để có được số lượng chính xác.

Trên máy tính của tôi, ví dụ đầu tiên tạo ra 8 đối tượng:

String s = "a"; 
s = s + "b"; 
s = s + "c"; 
  • hai đối tượng thuộc loại String;
  • hai đối tượng thuộc loại StringBuilder;
  • bốn đối tượng thuộc loại char[].

Mặt khác, ví dụ thứ hai:

StringBuffer sb = new StringBuffer("a"); 
sb.append("b"); 
sb.append("c"); 

tạo 2 đối tượng:

  • một đối tượng kiểu StringBuilder;
  • một đối tượng thuộc loại char[].

Điều này đang sử dụng JDK 1.6u30.

P.S. Để thực hiện hội chợ so sánh, bạn có thể phải gọi sb.toString() ở cuối ví dụ thứ hai.

+0

là máy tính này có phụ thuộc vào trình biên dịch không? –

+0

@AlexLockwood: Có lẽ JDK phụ thuộc vào một mức độ nào đó, mặc dù tôi khá ngạc nhiên nếu có nhiều thay đổi trong các JDK gần đây. – NPE

+0

Nó có vẻ khá ngớ ngẩn để phân biệt giữa một 'char []' và nó 'String' trừu tượng trong một ngôn ngữ cấp cao như Java: P. Nhưng tôi đồng ý nó là chính xác để làm như vậy (không ngớ ngẩn về phần của bạn ... chỉ ngớ ngẩn trong một loại ví dụ ngu ngốc như thế này). –

-1

Câu trả lời được gắn với các triển khai cụ thể của ngôn ngữ (các thư viện trình biên dịch và thời gian chạy). Ngay cả với sự hiện diện của các tùy chọn tối ưu hóa cụ thể hay không. Và, tất nhiên, phiên bản của việc thực hiện (và, ngầm nhiên, JLS nó phù hợp với). Vì vậy, nó tốt hơn để nói về minima và maxima. Trong thực tế, bài tập này cung cấp cho một tốt hơn

Đối với Ex1, số đối tượng tối thiểu là 1 (trình biên dịch nhận ra rằng chỉ có các hằng số liên quan và chỉ tạo mã cho String s= "abc" ;). Tối đa có thể chỉ là bất cứ điều gì, tùy thuộc vào việc thực hiện, nhưng ước tính hợp lý là 8 (cũng được đưa ra trong một câu trả lời khác như số được tạo ra bởi cấu hình nhất định).

Đối với Ex2, số đối tượng tối thiểu là 2. Trình biên dịch không có cách nào để biết nếu chúng ta đã thay thế StringBuilder bằng phiên bản tùy chỉnh với ngữ nghĩa khác nhau, vì vậy nó sẽ không tối ưu hóa. Tối đa có thể là khoảng 6, đối với việc triển khai StringBuilder bảo toàn bộ nhớ cực kỳ mở rộng một sự ủng hộ char[] mảng một ký tự cùng một lúc, nhưng trong hầu hết các trường hợp, nó cũng sẽ là 2.

+0

Trình biên dịch tạo ra mã cho 'String s =" abc ";' ', nhưng điều này không tạo ra một đối tượng khi được thực hiện, do đó minum thực ra là 0. – EJP

Các vấn đề liên quan