2012-01-07 52 views
25

Câu hỏi của tôi khá đơn giản:
Trình biên dịch có xử lý tất cả các phương thức trong lớp cuối cùng như là bản thân cuối cùng không? Việc thêm từ khóa final vào các phương thức trong lớp cuối cùng có ảnh hưởng gì không?Phương pháp không phải cuối cùng trong lớp cuối cùng

Tôi hiểu rằng các phương pháp cuối cùng có cơ hội tốt hơn để nhận được nội tuyến và đây là lý do tôi yêu cầu.

Xin cảm ơn trước.

Trả lời

26

Bạn đúng, tất cả các phương pháp trong lớp cuối cùng hoàn toàn là cuối cùng.

See here:

"Lưu ý rằng bạn cũng có thể tuyên bố toàn bộ một lớp cuối cùng. Một lớp học đó là tuyên bố chính thức không thể được subclassed. Điều này đặc biệt hữu ích, ví Ví dụ, khi tạo ra một lớp học bất biến như Chuỗi lớp. "

And here:

Tất cả các phương pháp trong một lớp học cuối cùng là mặc nhiên chính thức.

này cũng có thể quan tâm dành cho bạn: Performance tips for the Java final keyword

+2

Để trở thành thực thể, có hay không các phương pháp là hoàn toàn cuối cùng là tranh luận; không có cơ hội để cố gắng ghi đè chúng! –

+0

Điều này có nghĩa là trình biên dịch sẽ xử lý các phương thức đó là cuối cùng? (nội tuyến) @OliCharlesworth Đúng, nhưng có một sự khác biệt trong cách trình biên dịch xử lý các phương thức ảo và cuối cùng. – Acidic

+1

@Acidic: Xem liên kết thứ ba mà tôi vừa thêm vào. Bạn có thể không cần phải đi ra khỏi con đường của bạn để tuyên bố những điều như là cuối cùng. Nhưng có, với trình biên dịch, những phương thức đó được coi là "cuối cùng". – EboMike

5

Có thể là biên dịch xử lý chúng như thức.

Các bản in sau "false":

final class FinalClass { 
    public void testMethod() {} 
} 

Method method = FinalClass.class.getDeclaredMethod("testMethod"); 
int m = method.getModifiers(); 
System.out.println(Modifier.isFinal(m)); 
7

Liệu trình biên dịch xử lý tất cả các phương pháp trong một lớp học chính thức như là thức bản thân?

Có hiệu lực, có. Không thể ghi đè phương thức trong lớp final. Việc thêm (hoặc xóa) một từ khóa final vào một phương thức sẽ không có sự khác biệt với quy tắc này.

Việc thêm từ khóa cuối cùng vào các phương thức trong lớp cuối cùng có hiệu lực không?

Trong thực tế, nó có tác dụng tối thiểu. Nó không ảnh hưởng đến các quy tắc về trọng tài (xem ở trên) và không ảnh hưởng đến nội tuyến (xem bên dưới).

Có thể biết thời gian chạy nếu phương thức được khai báo bằng từ khóa final ... bằng cách sử dụng phản chiếu để xem cờ của phương thức. Vì vậy, nó có một số hiệu ứng, mặc dù có hiệu lực là nó không liên quan đến 99,99% chương trình.

Tôi hiểu rằng các phương pháp cuối cùng có cơ hội tốt hơn để nhận được nội tuyến và đây là lý do tôi hỏi.

Sự hiểu biết này là không chính xác.Trình biên dịch JIT trong một JVM hiện đại theo dõi các phương thức nào không được ghi đè trong các lớp được tải bởi bởi một ứng dụng. Nó sử dụng thông tin này và các kiểu tĩnh để xác định xem một cuộc gọi cụ thể có yêu cầu gửi lớp ảo hay không. Nếu không, thì nội tuyến là có thể, và sẽ được sử dụng tùy thuộc vào cơ thể phương thức lớn như thế nào. Trong thực tế, trình biên dịch JIT bỏ qua sự hiện diện/vắng mặt của final và sử dụng một phương pháp chính xác hơn để phát hiện các cuộc gọi phương thức trong đó nội tuyến của phương thức được cho phép. Một ứng dụng có thể tự động tải các lớp con gây ra phân tích ghi đè phương thức của trình biên dịch JIT để trở thành không chính xác.Nếu điều này xảy ra, JVM cần làm mất hiệu lực bất kỳ phương thức được biên dịch thực thi nào và khiến chúng trở thành . recompiled)


Điểm mấu chốt là:

  • There is NO lợi thế hiệu suất trong việc thêm final với các phương pháp trong final lớp.

  • thể là một lợi thế hiệu suất trong final với các phương pháp trong final lớp phi, nhưng chỉ khi bạn đang sử dụng một Sun JVM cũ, hoặc một số Java/Java giống như nền tảng khác với một trình biên dịch JIT chất lượng kém.

Nếu bạn quan tâm đến hiệu suất, nó là tốt hơn để sử dụng một/nền tảng Java hiệu suất cao up-to-date với một trình biên dịch JIT đàng hoàng hơn để gây ô nhiễm mã cơ sở của bạn với final từ khóa có chịu làm bạn vấn đề trong tương lai.


Bạn đã viết trong một chú thích:

@RussellZahniser Tôi đã đọc khác nhau ở nhiều nơi.

Internet có đầy đủ thông tin cũ, nhiều thông tin đã lỗi thời ... hoặc chưa bao giờ chính xác ở nơi đầu tiên.

+0

Cảm ơn bạn, đó là một bài đọc rất thú vị. Có bất kỳ thông tin chính thức hoặc một số loại thử nghiệm và kết quả cuối cùng về vấn đề này không? – Acidic

+0

Ngoài ra, trong một câu hỏi có liên quan tôi đã hỏi trước đây, tôi đã được dẫn dắt để hiểu rằng 'cuối cùng' phương pháp làm trong thực tế có một cơ hội cao hơn được inlined: http: // stackoverflow.com/questions/8639704/xác suất-of-getters-và-setters-nhận-in-the-compiler – Acidic

+1

@Acidic - sự hiểu biết của tôi là 'cuối cùng' không có sự khác biệt, và tôi biết không có bằng chứng thực sự mâu thuẫn với điều này . Nếu bạn thực sự muốn có một câu trả lời dứt khoát, hãy nhìn vào mã nguồn mở OpenJDK và xem những gì trình biên dịch JIT (s) thực sự làm. –

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