2012-12-15 44 views
6

cách thức hoạt động? Tôi dường như không thể tìm thấy câu trả lời.nguyên thủy-boolean Để ghép nối chuỗi/chuyển đổi

boolean bool=true; 
System.out.println("the value of bool is : " + true); 
//or 
System.out.println("the value of bool is : " + bool); 
  • gì được những điều mà đang xảy ra đằng sau cảnh?
  • Boolean được đúc như thế nào với chuỗi dưới dạng boolean không thể được ngụ ý là loại được truyền?
  • Có phải là Autoboxing/Unboxing có liên quan không?
  • Các phương pháp như toString() hoặc String.valueOf() có liên quan theo một cách nào đó không?
+2

Đọc bài viết này: http://www.znetdevelopment.com/blogs/2009/04/06/java-string-concatenation/ –

Trả lời

13

Các quy tắc chính xác được nêu rõ trong ngôn ngữ Java Specification, §5.1.11. String Conversion

Theo những quy tắc, "str" + bool tương đương với:

"str" + new Boolean(bool).toString() 

Điều đó nói rằng, trình biên dịch được phép mất nhiều thời gian đáng kể trong cách chính xác biểu thức tổng thể được đánh giá. Từ JLS §15.18.1. String Concatenation Operator +:

Thực hiện có thể chọn thực hiện chuyển đổi và ghép nối trong một bước để tránh tạo và loại bỏ đối tượng Chuỗi trung gian. Để tăng hiệu suất của chuỗi nối lặp lại, trình biên dịch Java có thể sử dụng lớp StringBuffer hoặc một kỹ thuật tương tự để giảm số đối tượng trung gian String được tạo bằng cách đánh giá biểu thức.

Đối với các loại nguyên thủy, triển khai cũng có thể tối ưu hóa việc tạo đối tượng bao bọc bằng cách chuyển đổi trực tiếp từ kiểu gốc thành chuỗi.

Ví dụ, với trình biên dịch của tôi như sau:

boolean bool = true; 
System.out.println("the value of bool is : " + bool); 

là chính xác tương đương với:

boolean bool = true; 
System.out.println(new StringBuilder("the value of bool is : ").append(bool).toString()); 

Họ kết quả trong bytecode giống hệt nhau:

Code: 
    0: iconst_1  
    1: istore_1  
    2: getstatic  #59     // Field java/lang/System.out:Ljava/io/PrintStream; 
    5: new   #166    // class java/lang/StringBuilder 
    8: dup   
    9: ldc   #168    // String the value of bool is : 
    11: invokespecial #170    // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    14: iload_1  
    15: invokevirtual #172    // Method java/lang/StringBuilder.append:(Z)Ljava/lang/StringBuilder; 
    18: invokevirtual #176    // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    21: invokevirtual #69     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
    24: return   
+1

thực tế là cả hai đoạn mã tạo cùng một bytecode nhất thiết có nghĩa là IS trước đây được chuyển đổi thành mã sau?(trước khi được chuyển đổi sang bytecode, nghĩa là) –

+0

@VinayWadhwa Tôi không nghĩ rằng JLS chỉ định * cách * bạn nên triển khai chuỗi nối - chỉ đơn thuần là kết quả là gì. Tuy nhiên, theo như tôi có thể nhớ, trình biên dịch Java của Snorcle đã thực hiện nó bằng cách sử dụng một 'StringBuffer', sau đó là một' StringBuilder'. Nó có lẽ hoàn toàn được phép có chuỗi nối là một hoạt động nội tại trong JVM của bạn. – millimoose

+0

@VinayWadhwa Điều này dường như được ngụ ý bởi [§15.18.1] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.18.1): " Để tăng hiệu suất của chuỗi nối lặp lại, trình biên dịch Java có thể sử dụng lớp StringBuffer hoặc kỹ thuật tương tự… "và" Đối với các kiểu nguyên thủy, việc triển khai cũng có thể tối ưu hóa việc tạo đối tượng bao bọc ... " – millimoose

2

Đó là điều trình biên dịch. Nếu toán hạng phù hợp cho phép nối là một đối tượng, đối tượng được gửi phương thức toString() trong khi toán hạng là nguyên thủy thì trình biên dịch biết hành vi kiểu cụ thể nào sẽ sử dụng để chuyển đổi nguyên thủy thành một Chuỗi.

+0

tôi thấy .. bạn có thể chỉ cho tôi một tài liệu nêu rõ điều đó không? –

+0

@VinayWadhwa: xem câu trả lời của tôi để tham khảo. –

2

Trình biên dịch chuyển nó đến

StringBuilder sb = new StringBuilder("the value of bool is : "); 
sb.append(true); 
System.out.println(sb.toString()); 

Quy tắc ghép nối và chuyển đổi được giải thích trong the JLS.

+0

trình biên dịch nào? mọi trình biên dịch? nếu bạn có thể chỉ cho tôi nguồn gốc của thông tin này, nó sẽ được đánh giá cao. Tham chiếu bạn cung cấp không liên quan đến câu trả lời của bạn, tôi nghĩ .. –

+0

Nó nói: * Việc triển khai có thể chọn thực hiện chuyển đổi và ghép nối trong một bước để tránh tạo và sau đó loại bỏ đối tượng Chuỗi trung gian. Để tăng hiệu suất của chuỗi nối lặp lại, một trình biên dịch Java có thể sử dụng lớp StringBuffer hoặc một kỹ thuật tương tự để giảm số đối tượng String trung gian được tạo ra bằng cách đánh giá một biểu thức. * Để biết các quy tắc, hãy đọc JLS. Để biết nó hoạt động như thế nào, hãy đọc bytecode được tạo bởi trình biên dịch của bạn. –