Có thể tối ưu hóa tôi có thể áp dụng cho một trong các phương pháp của tôi, nếu tôi có thể xác định rằng một phương thức khác trong cùng một lớp không bị ghi đè. Nó chỉ là một tối ưu hóa nhỏ, vì vậy phản ánh là ra khỏi câu hỏi. Tôi có nên chỉ thực hiện một phương thức được bảo vệ trả về cho dù phương thức được đề cập có bị ghi đè hay không, sao cho một lớp con có thể làm cho nó trở về đúng?Làm thế nào để nhanh chóng xác định xem một phương pháp có bị ghi đè trong Java
Trả lời
Tôi sẽ không làm điều này. Nó vi phạm đóng gói và thay đổi hợp đồng của những gì lớp học của bạn có nghĩa vụ phải làm mà không có người thực hiện biết về nó.
Nếu bạn phải làm điều đó, tuy nhiên, cách tốt nhất là để gọi
class.getMethod("myMethod").getDeclaringClass();
Nếu lớp học đó là quay trở lại là của riêng bạn, sau đó nó không ghi đè; nếu nó là cái gì khác, phân lớp đó đã ghi đè nó. Vâng, đây là sự phản ánh, nhưng nó vẫn còn khá rẻ.
Tuy nhiên, tôi thực sự thích phương thức bảo vệ phương pháp của bạn. Điều đó sẽ trông giống như sau:
public class ExpensiveStrategy {
public void expensiveMethod() {
// ...
if (employOptimization()) {
// take a shortcut
}
}
protected boolean employOptimization() {
return false;
}
}
public class TargetedStrategy extends ExpensiveStrategy {
@Override
protected boolean employOptimization() {
return true; // Now we can shortcut ExpensiveStrategy.
}
}
Vâng, tối ưu hóa của tôi là một lợi nhuận nhỏ trên cơ sở từng trường hợp, và nó chỉ tăng tốc độ nhiều thứ bởi vì nó được gọi là hàng trăm lần mỗi giây. Với sự phản ánh, năng suất đó sẽ giảm xuống đến mức tối ưu hóa là vô nghĩa. Một câu trả lời tốt, vì vậy tôi sẽ upvoting anyways này. – bgw
Nếu bạn thực sự thực sự cần nó, bạn có thể xác định xem các phương thức (s) bị quá tải thông qua trong một initialiser tĩnh và lưu trữ kết quả trong một boolean. Ngoài ra, bạn có thể thêm điều này thông qua aspectj – vickirk
Sử dụng Class.getMethod để thay thế. Class.getDeclaredMethod sẽ tăng NoSuchMethodException nếu bạn hỏi về một phương thức kế thừa mà lớp con không ghi đè lên. Tất nhiên, bạn có thể sử dụng ngoại lệ như là một chỉ báo (nghèo) rằng phương pháp này không được overriden. –
Bạn mong đợi bao nhiêu lần chức năng được gọi trong suốt thời gian tồn tại của chương trình? Phản ánh cho một phương thức cụ thể không nên quá tệ. Nếu nó không phải là giá trị mà nhiều thời gian trong suốt cuộc đời của chương trình khuyến nghị của tôi là để giữ cho nó đơn giản, và không bao gồm tối ưu hóa nhỏ.
Jacob
Nó là một phương pháp rất phổ biến. – bgw
Hãy để tôi làm rõ câu trả lời của tôi. Tôi đã gợi ý rằng nếu bạn có mẫu phổ biến này, và các cá thể là tất cả cùng loại, bạn có thể cache giá trị của sự phản chiếu được thực hiện một lần. Bạn xác định cấu hình lần đầu tiên và sử dụng giá trị đó trong suốt. Bằng cách này, chi phí phản chiếu sẽ là một thời gian và các cuộc gọi sẽ là một con số lớn hơn nhiều. Nếu điều này được gọi lặp đi lặp lại trên mỗi cá thể, một biến cá thể được khai báo trong lớp cha và lười được khởi tạo trong lần gọi đầu tiên (sử dụng sự phản chiếu) có thể giúp bạn tăng cường. – TheJacobTaylor
Phản ánh có thể được sử dụng để xác định xem phương pháp có bị ghi đè hay không. Mã này hơi phức tạp một chút. Ví dụ, bạn cần phải biết rằng bạn có một lớp thời gian chạy là lớp con của lớp ghi đè phương thức.
Bạn sẽ thấy cùng các lớp thời gian chạy lặp đi lặp lại. Vì vậy, bạn có thể lưu kết quả của séc vào một số WeakHashMap
được đánh dấu trên Class
.
Xem mã của tôi trong java.awt.Component
giao dịch với coalesceEvents
để biết ví dụ.
không có thể làm, giá trị thay đổi một chút mỗi lần. – bgw
@PiPeep: Ví dụ thực tế không liên quan. Như tôi đã nói, khóa bản đồ dựa trên lớp thời gian chạy. –
Chú thích các lớp con ghi đè phương pháp cụ thể. @OverridesMethodX.
Thực hiện công việc phản chiếu cần thiết về tải lớp học (ví dụ: trong khối static
) để bạn xuất bản thông tin qua cờ boolean cuối cùng. Sau đó, truy vấn cờ ở đâu và khi nào bạn cần.
các khối tĩnh ngắt kế thừa. – bgw
Tôi biết nó có mùi. Nhưng tối ưu hóa bạn muốn là đã lật đổ đa hình. –
Vâng, tối ưu hóa của tôi là một lợi nhuận nhỏ trên cơ sở từng trường hợp, và nó chỉ tăng tốc độ nhiều thứ bởi vì nó được gọi là hàng trăm lần mỗi giây.
Bạn có thể muốn xem chỉ những gì trình tối ưu hóa Java có thể thực hiện. Tối ưu hóa mã hóa bằng tay của bạn có thể không cần thiết.
Nếu bạn quyết định tối ưu hóa mã hóa bằng tay là cần thiết, cách tiếp cận phương pháp được bảo vệ mà bạn mô tả không phải là ý tưởng hay vì nó cho thấy chi tiết về việc triển khai của bạn.
+1 Có vẻ như lời khuyên tốt cho tôi, không biết tại sao nó lại bị bỏ phiếu. – vickirk
có thể có cách sạch hơn để thực hiện điều này qua Strategy Pattern, mặc dù tôi không biết phần còn lại của ứng dụng và dữ liệu của bạn được mô hình hóa như thế nào nhưng có vẻ như nó có thể phù hợp.
Nó đã làm cho tôi dù sao đi nữa khi tôi gặp phải vấn đề tương tự.Bạn có thể có một heuristic quyết định chiến lược nào sẽ sử dụng tùy thuộc vào dữ liệu được xử lý.
Một lần nữa, tôi không có đủ thông tin về mức sử dụng cụ thể của bạn để xem đây có phải là quá mức cần thiết hay không. Tuy nhiên tôi sẽ không thay đổi chữ ký của lớp để tối ưu hóa cụ thể như vậy. Thông thường khi tôi cảm thấy sự thôi thúc chống lại hiện tại, tôi coi nó như một bài hát mà tôi đã không nhìn thấy một trường hợp góc khi tôi thiết kế điều đó và tôi nên refactor nó đến một giải pháp toàn diện sạch hơn.
tuy nhiên hãy cẩn thận, việc tái cấu trúc như vậy chỉ được thực hiện trên cơ sở tối ưu hóa gần như chắc chắn dẫn đến thảm họa. Nếu đây là trường hợp tôi sẽ có cách tiếp cận phản xạ gợi ý ở trên. Nó không làm thay đổi hợp đồng thừa kế, và khi thực hiện đúng cách cần được thực hiện một lần duy nhất cho mỗi lớp con yêu cầu nó cho thời gian chạy của ứng dụng.
Tôi biết đây là một câu hỏi hơi cũ, nhưng vì lợi ích của người dùng Google khác:
tôi đã đưa ra một giải pháp khác nhau sử dụng giao diện.
class FastSub extends Super {}
class SlowSub extends Super implements Super.LetMeHandleThis {
void doSomethingSlow() {
//not optimized
}
}
class Super {
static interface LetMeHandleThis {
void doSomethingSlow();
}
void doSomething() {
if (this instanceof LetMeHandleThis)
((LetMeHandleThis) this).doSomethingSlow();
else
doSomethingFast();
}
private final void doSomethingFast() {
//optimized
}
}
hoặc cách khác xung quanh:
class FastSub extends Super implements Super.OptimizeMe {}
class SlowSub extends Super {
void doSomethingSlow() {
//not optimized
}
}
class Super {
static interface OptimizeMe {}
void doSomething() {
if (this instanceof OptimizeMe)
doSomethingFast();
else
doSomethingSlow();
}
private final void doSomethingFast() {
//optimized
}
void doSomethingSlow(){}
}
private static boolean isMethodImplemented(Object obj, String name)
{
try
{
Class<? extends Object> clazz = obj.getClass();
return clazz.getMethod(name).getDeclaringClass().equals(clazz);
}
catch (SecurityException e)
{
log.error("{}", e);
}
catch (NoSuchMethodException e)
{
log.error("{}", e);
}
return false;
}
Bạn đã đăng chính xác câu trả lời ở đây và [tại đây] (http://stackoverflow.com/questions/4821704/java-how-to-find-if-a-method-is-overridden-from-base-class/19637356# 19637356). Nếu bạn có thể trả lời chính xác thì bạn nên đánh dấu ** câu hỏi là trùng lặp **, ** không trùng lặp câu trả lời ** quá. –
- 1. Làm thế nào để nhanh chóng triển khai/ghi đè các phương thức trong Eclipse?
- 2. Một cách nhanh chóng để xác định xem một Componet có được tìm thấy trong JPanel
- 3. Java: Cách kiểm tra xem một phương pháp có bị ghi đè hay không, sử dụng phản chiếu
- 4. Cách xác định phương pháp ghi đè trong mã byte Java?
- 5. Cách nhanh chóng để xác định xem một PID có tồn tại trên (Windows) không?
- 6. Làm thế nào để xác định nếu MethodInfo là một ghi đè của phương pháp cơ sở
- 7. Java: Gọi một phương pháp siêu trong đó kêu gọi một phương pháp ghi đè
- 8. Cách nhanh chóng để xác định xem một trường tồn tại trong bảng ORACLE
- 9. Làm thế nào để nhanh chóng thử nghiệm mã Java?
- 10. Làm thế nào để xác định một phương pháp riêng
- 11. Tìm phương pháp ghi đè
- 12. Làm thế nào để ghi đè lên một phương pháp variadic trong Objective-C
- 13. Làm thế nào để xác định xem một phương pháp là một trường hợp chung của một phương pháp chung
- 14. Có an toàn để ghi đè lên một phương pháp được xác định trong Mục tiêu-C không?
- 15. Có thể xác định/khẳng định, rằng nếu một hàm ảo bị ghi đè, một hàm khác cũng bị ghi đè?
- 16. Phương pháp riêng trong siêu lớp có bị ghi đè trong phân lớp không?
- 17. Các phương pháp ghi đè trong JavaDoc
- 18. Làm thế nào để ngăn chặn một hàm bị ghi đè trong python
- 19. Java: Cách ghi đè phương pháp chung này?
- 20. Ghi đè bằng phương pháp trong DTO's
- 21. Làm thế nào nguy hiểm trong JavaScript, thực sự, giả định không xác định không bị ghi đè?
- 22. Làm thế nào để tái xác định một phương pháp trong "lớp javascript" một
- 23. Làm thế nào để nhanh chóng in các băm Ruby trong một định dạng bảng?
- 24. Làm thế nào ổn định và nhanh chóng là HtmlUnit
- 25. Làm rõ phương pháp ghi đè lên trộn bằng Ruby
- 26. C# "Không tìm thấy phương pháp phù hợp để ghi đè." - nhưng có một
- 27. Ghi đè phương pháp được bảo vệ
- 28. Gọi một phương pháp ghi đè từ một constructor
- 29. Có cách nào trong C# để ghi đè lên một phương thức lớp với một phương pháp mở rộng?
- 30. Tôi có thể phát hiện ra rằng một phương pháp đã bị ghi đè không?
Làm thế nào về chỉ không tối ưu hóa nó? Có vẻ như việc tối ưu hóa không đủ quan trọng để thực sự quan trọng. –
Anon: Phương pháp này được gọi là hàng trăm lần mỗi giây. – bgw
Sau đó, đi để phản ánh, và bộ nhớ cache kết quả trong một lĩnh vực tư nhân. –