2015-01-21 14 views
5

Giả sử chúng ta có một lớp:Anonymous khởi của lớp với constructor bảo vệ

public class SomeClass {  
    protected SomeClass() { 
    } 
} 

Trong MainClass nằm trong gói phần mềm khác nhau tôi đã cố gắng để thực hiện hai dòng:

public static void main(String[] args) { 
    SomeClass sac1 = new SomeClass(); 
    SomeClass sac2 = new SomeClass() {}; 
} 

Do protected constructor, trong cả hai trường hợp tôi đã mong đợi chương trình thất bại. Để tôi ngạc nhiên, khởi tạo vô danh làm việc tốt. Ai đó có thể giải thích cho tôi tại sao phương pháp khởi tạo thứ hai là ok?

Trả lời

8

lớp ẩn danh của bạn

SomeClass sac2 = new SomeClass() {}; 

về cơ bản trở thành

public class Anonymous extends SomeClass { 
    Anonymous() { 
     super(); 
    } 
} 

Các nhà xây dựng không có sửa đổi lần truy cập, vì vậy bạn có thể gọi nó mà không có vấn đề từ bên trong cùng một gói. Bạn cũng có thể gọi super() vì hàm tạo protected cha mẹ có thể truy cập từ một hàm tạo lớp con.

+0

Tôi rất ngạc nhiên, điều tương tự cũng xảy ra khi bạn sử dụng một hàm tạo không có đối số. Trong trường hợp này tôi nghĩ rằng lời giải thích của bạn không còn đứng. – Andrei

+0

@Andrei Tôi không đề cập đến tham số/đối số. Chúng không có vai trò trong kiểm tra khả năng truy cập. –

+0

Không có trong kiểm tra accesibility, không. Nhưng nếu bạn có một lớp với chỉ một constructor được bảo vệ WITH params, bạn phải gọi một cách rõ ràng constructor của nó với các tham số, từ con. Tôi đã nói rằng quy tắc này dường như bị bỏ qua cho các lớp ẩn danh. – Andrei

3

Dòng đầu tiên thất bại, vì SomeClass 'constructor s là protectedMainClass không có trong SomeClass' gói s, và nó không được subclassing MainClass.

Dòng thứ hai thành công vì nó đang tạo một lớp con ẩn danh là SomeClass. Lớp bên trong ẩn danh này lớp con SomeClass, do đó, nó có quyền truy cập vào SomeClass 's protected hàm tạo. Hàm khởi tạo mặc định cho lớp bên trong ẩn danh này ngầm ngầm gọi hàm tạo của lớp bậc trên này.

0

dòng của bạn

SomeClass sac2 = new SomeClass() {}; 

tạo ra một thể hiện của một lớp học mới mà mở rộng SomeClass. Vì SomeClass định nghĩa một hàm tạo được bảo vệ không có đối số, một lớp con có thể gọi hàm này ngầm trong hàm tạo riêng của nó đang xảy ra trong dòng này.

2

Hai niềng răng ít trong

SomeClass sac2 = new SomeClass() {}; 

gọi rất nhiều hành vi tự động trong Java. Dưới đây là những gì xảy ra khi dòng đó được thực thi:

  1. Một phân lớp ẩn danh SomeClass được tạo.
  2. Lớp con ẩn danh đó được cung cấp một hàm tạo không đối số mặc định, giống như bất kỳ lớp Java nào khác được khai báo mà không có hàm tạo không có đối số.
  3. Hàm tạo không đối số mặc định được xác định với chế độ hiển thị public
  4. Hàm tạo không đối số mặc định được định nghĩa để gọi super() (đó là những gì nhà thầu no-arg luôn làm trước).
  5. Lệnh new gọi hàm tạo không đối số của phân lớp ẩn danh này và gán kết quả cho sac2.

Giá trị mặc định không tham số constructor trong lớp con nặc danh của SomeClass có quyền truy cập vào các protected constructor của SomeClass vì lớp con nặc danh là một hậu duệ của SomeClass, vì vậy cuộc gọi đến super() là hợp lệ. Câu lệnh new gọi hàm tạo không đối số mặc định này, có độ hiển thị là public.

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