2014-11-19 16 views
13

Hãy xem xét ví dụ nhỏ sau:getDeclaredMethods() hành xử khác nhau trong Java 7 vs Java 8

package prv.rli.codetest; 

import java.lang.reflect.Method; 

public class BreakingInterfaces { 
    interface Base { 
     BaseFoo foo(); 
     interface BaseFoo {   
     } 
    } 

    interface Derived extends Base { 
     DerivedFoo foo(); 
     interface DerivedFoo extends BaseFoo { 

     } 
    } 

    public static void main(String[] args) {  
     dumpDeclaredMethods(Derived.class); 
    } 

    private static void dumpDeclaredMethods(Class<?> class1) { 
     System.out.println("---" + class1.getSimpleName() + "---"); 
     Method[] methods = class1.getDeclaredMethods(); 
     for (Method method : methods) { 
      System.out.println(method); 
     } 
     System.out.println("----------"); 
    } 
} 

Nếu bạn biên dịch ví dụ trên với jdk1.7.0.55 đầu ra là:

---Derived--- 
public abstract BreakingInterfaces$Derived$DerivedFoo BreakingInterfaces$Derived.foo() 
---------- 

Nhưng khi sử dụng jdk1.8.0.25 đầu ra là:

---Derived--- 
public abstract prv.rli.codetest.BreakingInterfaces$Derived$DerivedFoo prv.rli.codetest.BreakingInterfaces$Derived.foo() 
public default prv.rli.codetest.BreakingInterfaces$Base$BaseFoo prv.rli.codetest.BreakingInterfaces$Derived.foo() 
---------- 

Không ai biết, cho dù đây là một lỗi trong jdk1.8.0.25 hoặc tại sao p phương pháp mặc định công cộng resurfaces ở đây?

+2

'm đoán ở đây, nhưng nó có thể là một cái gì đó để làm với java8 mặc định thực hiện các phương pháp trong giao diện. – user902383

Trả lời

14

getDeclaredMethods() hoạt động chính xác tại đây vì nó cho bạn biết chính xác nội dung đã tìm thấy trong lớp học. Nếu bạn nạp vào một interface được biên dịch với mục tiêu Java 7 (hoặc một trình biên dịch cũ hơn), bạn sẽ thấy không có sự khác biệt với đầu ra của việc triển khai Java 7 là getDeclaredMethods().

Trình biên dịch hoạt động khác nhau. Khi biên dịch như một sub2 interface trong Java 8, một phương thức bridge sẽ được tạo ra sẽ không được tạo ra cho một mục tiêu Java 7 vì nó thậm chí không thể cho đích Java 7.

Lý do tại sao phương thức cầu được tạo cho giao diện hiện tại là bạn thường có nhiều lớp triển khai hơn giao diện, do đó có phương pháp cầu default trong giao diện giúp bạn không thêm phương thức cầu đó vào mỗi lần triển khai. Hơn nữa, nó làm cho việc tạo lớp lambda dễ dàng hơn nhiều nếu chỉ có một phương thức abstract và không có phương thức bridge nào để thực hiện.

Khi phân cấp interface yêu cầu phương thức cầu nhưng không cung cấp default s, trình biên dịch phải tạo mã bằng cách sử dụng LambdaMetafactory.altMetafactory thay vì chỉ định mọi phương thức cầu được yêu cầu.

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