2016-03-07 15 views
17

Tôi vào giải quyết một số câu đố Java và vấp vào một này:JDK 1.7 vs JDK 1.6 lớp bên chênh lệch thừa kế

public class Outer { 
    class Inner1 extends Outer {} 
    class Inner2 extends Inner1 {} 
} 

Trong khi biên dịch mã này với javac 1.6.0_45 tôi nhận được, như mong đợi, lỗi này:

Outer.java:8: cannot reference this before supertype constructor has been called 
class Inner2 extends Inner1 {}                         
^ 

Điều này là do các trình biên dịch tạo ra constructor mặc định cho Inner2 lớp với mã tương tự, điều này giải thích lỗi trên:

Inner2() { 
    this.super(); 
} 

Và nó rõ ràng bây giờ, bởi vì bạn thực sự không thể làm điều này trong Java 1.6.0_45, JLS 8.8.7.1 (như tôi có thể đoán):

An explicit constructor invocation statement in a constructor body may not refer to any instance variables or instance methods declared in this class or any superclass, or use this or super in any expression; otherwise, a compile-time error occurs.

See (accepted answer trong Odd situation for "cannot reference this before supertype constructor has been called")

Nhưng nếu tôi cố gắng biên dịch nó với javac 1.7.0_79 - OK!

Và đây là câu hỏi - Điều gì đã được thay đổi trong Java 1.7, mã này hiện đã chính xác chưa?

Cảm ơn trước!

+3

@EJP bạn đã kiểm tra [câu trả lời được chấp nhận] (http://stackoverflow.com/a/3383555/365237) của cái đó, vì cái đó có vẻ có liên quan – eis

+2

@EJP, cũng, 'this.super() 'is ** not ** tương đương với' super() '. Nếu bạn cố gắng làm điều này trong lớp không lồng bên trong, bạn sẽ gặp phải lỗi biên dịch, trước khi [JLS1.6 8.8.7.1]. 'Nếu S không phải là một lớp bên trong, hoặc nếu khai báo của S xảy ra trong một bối cảnh tĩnh, không có trường hợp bao bọc ngay lập tức của i đối với S tồn tại. Lỗi compiletime xảy ra nếu lời gọi hàm tạo của lớp bậc trên là một lời gọi hàm tạo của lớp bậc trên đủ điều kiện.' Tương tự như [JLS1.7 8.8.7.1]. – ar4ers

Trả lời

6

vẻ như đã xảy thảo luận về các vấn đề tương tự như lỗi JDK-6708938: Synthetic super-constructor call should never use 'this' as a qualifier trên theo dõi lỗi Java lambda .

Ngoài ra, tôi nghĩ bạn nên xem các vấn đề khác có liên quan của trang trước, ví dụ: JDK-4903103: Can't compile subclasses of inner classes .

Thông báo Phiên bản cố định của cả hai lỗi.

Và kết quả là xem Maintenance Review of JSR 901 (Java Language Specification) for Java SE 7.

Từ The Java Language Specification Third Edition

Otherwise, S is an inner member class (§8.5). It is a compile-time error if S is not a member of a lexically enclosing class, or of a superclass or superinterface thereof. Let O be the innermost lexically enclosing class of which S is a member, and let n be an integer such that O is the n th lexically enclosing class of C . The immediately enclosing instance of i with respect to S is the n th lexically enclosing instance of this.

Và từ Maintenance Rà soát JSR 901 (Java Language Specification) cho Java SE 7 (phiên bản đầy đủ, trang 242, dòng chữ màu xanh) hoặc giống nhau ở The Java Language Specification, Java SE 7 Edition (ngay trước phần 8.8. 8)

Otherwise, S is an inner member class (§8.5).

Let O be the innermost lexically enclosing class of S, and let n be an integer such that O is the n'th lexically enclosing class of C.

The immediately enclosing instance of i with respect to S is the n'th lexically enclosing instance of this.

Vì vậy, bạn có thể thấy rằng phần có lỗi biên dịch đã biến mất.

+0

Cảm ơn bạn đã trả lời! Bây giờ tôi có một đầu mối rằng một cái gì đó chắc chắn đã được thay đổi! Nhưng tôi không hiểu chính xác. Tôi không tìm thấy bất kỳ sự khác biệt lớn giữa 'JLS SE 7' và' JLS Third Edition' trong toàn bộ 8,8 phần. – ar4ers

+1

@ ar4ers Tôi đã thêm vào sự khác biệt của hai phiên bản JSL này liên quan đến vấn đề này. – NikolayKondratyev

+0

Cảm ơn bạn đã ghi chú bổ sung! Bây giờ tôi hiểu sự khác biệt. Và, có thể bạn cũng biết, nơi có thể tìm thấy định nghĩa hành vi cụ thể (như tạo dựng hàm tạo tổng hợp)? Như tôi có thể đoán - đó là JVMS, tôi có đúng không? – ar4ers

-1

tôi nghi ngờ đó là đã làm với invoke dynamic được thêm vào trong java 1.7 để chuẩn bị cho trong java 8.

+0

Tôi đã kiểm tra nó ngay từ đầu. Đáng buồn thay, nó không phải là. Tôi đã sử dụng 'javap -c' trên tất cả ba tệp' .class', 'Outer.class',' Outer $ Inner1.class' và 'Outer $ Inner2.class'.Không có bằng chứng về "động lực", chỉ có 'invokespecial' và' putfield'. Tôi hiện đang điều tra về vấn đề này, nhưng chưa có kết quả. – ar4ers

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