Câu trả lời:
Khả năng hiển thị mặc định được gọi là “package-private” (mặc dù bạn không thể sử dụng nó một cách rõ ràng), có nghĩa là trường sẽ có thể truy cập được từ bên trong cùng một gói mà lớp thuộc về.
Như mdma đã chỉ ra, nó không đúng với các thành viên giao diện, mặc định là "công khai".
Thông số kỹ thuật mặc định phụ thuộc vào ngữ cảnh.
Đối với các lớp và khai báo giao diện, mặc định là gói riêng tư. Điều này nằm giữa được bảo vệ và riêng tư, chỉ cho phép các lớp trong cùng một gói truy cập. (được bảo vệ giống như thế này, nhưng cũng cho phép truy cập vào các lớp con bên ngoài gói.)
class MyClass // package private
{
int field; // package private field
void calc() { // package private method
}
}
Đối với các thành viên giao diện (trường và phương thức), quyền truy cập mặc định là công khai. Nhưng lưu ý rằng bản thân khai báo giao diện được mặc định là gói riêng tư.
interface MyInterface // package private
{
int field1; // static final public
void method1(); // public abstract
}
Nếu sau đó chúng ta có khai báo
public interface MyInterface2 extends MyInterface
{
}
Các lớp sử dụng MyInterface2 sau đó có thể thấy field1 và method1 từ siêu giao diện, bởi vì chúng là công khai, mặc dù chúng không thể nhìn thấy phần khai báo của chính MyInterface.
/* pp */
) chỉ là một tên thuận tiện cho truy cập mặc định . Nó không phải là tên JLS.
Nếu không có mã xác định quyền truy cập nào được cung cấp, thì đó là quyền truy cập mức gói (không có mã xác định rõ ràng cho điều này) cho các lớp và thành viên lớp. Các phương thức giao diện là công khai hoàn toàn.
Khả năng hiển thị mặc định (không có từ khóa) là gói có nghĩa là nó sẽ có sẵn cho mọi lớp nằm trong cùng một gói.
Lưu ý bên cạnh thú vị là được bảo vệ không giới hạn khả năng hiển thị đối với các lớp con mà còn đối với các lớp khác trong cùng một gói
Nó phụ thuộc vào sự vật là gì.
Các kiểu cấp cao nhất (nghĩa là các lớp, enums, giao diện và các kiểu chú thích không được khai báo bên trong một kiểu khác) theo mặc định là gói riêng tư . ( JLS §6.6.1 )
Trong các lớp, tất cả các thành viên (có nghĩa là các trường, phương thức và khai báo kiểu lồng nhau) và các hàm tạo là gói riêng theo mặc định. ( JLS §6.6.1 )
Trong enums, các hàm tạo là private theo mặc định. Thật vậy, enum contructors phải là private, và việc chỉ định chúng là public hay protected là một lỗi. Hằng số enum luôn là công khai và không cho phép bất kỳ mã xác định quyền truy cập nào. Các thành viên khác của enums là gói-riêng theo mặc định. ( JLS §8.9 )
Trong giao diện và kiểu chú thích, tất cả các thành viên (một lần nữa, điều đó có nghĩa là các trường, phương thức và khai báo kiểu lồng nhau) là công khai theo mặc định. Thật vậy, các thành viên của các giao diện và các loại chú thích phải ở chế độ công khai, và việc chỉ định chúng là riêng tư hoặc được bảo vệ là một lỗi. ( JLS §9.3 đến 9.5 )
Các lớp cục bộ là các lớp được đặt tên được khai báo bên trong một phương thức, phương thức khởi tạo hoặc khối khởi tạo. Chúng nằm trong phạm vi {
.. }
khối mà chúng được khai báo và không cho phép bất kỳ trình xác định quyền truy cập nào. ( JLS §14.3 ) Sử dụng phản chiếu, bạn có thể khởi tạo các lớp cục bộ từ nơi khác và chúng là gói riêng tư , mặc dù tôi không chắc liệu chi tiết đó có trong JLS hay không.
Các lớp ẩn danh là các lớp tùy chỉnh được tạo ra new
để chỉ định một phần thân của lớp trực tiếp trong biểu thức. ( JLS §15.9.5 ) Cú pháp của chúng không cho phép bất kỳ trình xác định quyền truy cập nào. Bằng cách sử dụng phản chiếu, bạn có thể khởi tạo các lớp ẩn danh từ nơi khác và cả chúng và các hàm tạo được tạo của chúng đều là gói riêng tư , mặc dù tôi không chắc liệu chi tiết đó có trong JLS hay không.
Các khối khởi tạo phiên bản và tĩnh không có mã xác định truy cập ở cấp ngôn ngữ ( JLS §8.6 & 8.7 ), nhưng các khối khởi tạo tĩnh được triển khai dưới dạng một phương thức có tên <clinit>
( JVMS §2.9 ), do đó, trong nội bộ phương thức phải có một số chỉ định truy cập. Tôi đã kiểm tra các lớp được biên dịch bởi javac và bởi trình biên dịch của Eclipse bằng trình soạn thảo hex và thấy rằng cả hai đều tạo ra phương thức dưới dạng gói-riêng . Tuy nhiên, bạn không thể gọi <clinit>()
trong ngôn ngữ bởi vì các ký tự <
và >
không hợp lệ trong tên phương thức và các phương thức phản chiếu được làm cứng để phủ nhận sự tồn tại của nó, do đó, chỉ định truy cập của nó thực sự là không có quyền truy cập . Phương thức chỉ có thể được gọi bởi VM, trong quá trình khởi tạo lớp.Các khối khởi tạo phiên bản không được biên dịch thành các phương thức riêng biệt; mã của chúng được sao chép vào mỗi phương thức khởi tạo, vì vậy chúng không thể được truy cập riêng lẻ, ngay cả khi phản chiếu.
default là một từ khóa được sử dụng làm công cụ sửa đổi quyền truy cập cho các phương thức và biến.
Việc sử dụng công cụ sửa đổi quyền truy cập này sẽ làm cho lớp, biến, phương thức hoặc hàm tạo của bạn có thể sử dụng được từ lớp hoặc gói riêng, nó cũng sẽ được đặt nếu không có công cụ sửa đổi truy cập nào.
Access Levels
Modifier Class Package Subclass EveryWhere
public Y Y Y Y
protected Y Y Y N
default Y Y N N
private Y N N N
nếu bạn sử dụng mặc định trong một giao diện, bạn sẽ có thể triển khai một phương thức ở đó như ví dụ này
public interface Computer {
default void Start() {
throw new UnsupportedOperationException("Error");
}
}
Tuy nhiên nó sẽ chỉ hoạt động từ phiên bản Java 8
Xem tại đây để biết thêm chi tiết. Mặc định không phải là private / public / protected mà là một đặc tả truy cập hoàn toàn khác. Nó không được sử dụng rộng rãi và tôi thích cụ thể hơn nhiều trong các định nghĩa truy cập của mình.
Dưới đây là trích dẫn về khả năng hiển thị ở cấp độ gói từ cuộc phỏng vấn với James Gosling, người tạo ra Java:
Bill Venners : Java có bốn cấp độ truy cập. Mặc định là gói. Tôi luôn tự hỏi liệu việc đặt quyền truy cập gói mặc định có thuận tiện không vì ba từ khóa mà mọi người từ C ++ đã biết là private, protected và public. Hoặc nếu bạn có một số lý do cụ thể mà bạn cảm thấy quyền truy cập gói phải là mặc định.
James Gosling : Một gói thường là một tập hợp những thứ được viết cùng nhau. Vì vậy, nói chung, tôi có thể làm một trong hai điều. Một là buộc bạn luôn phải đặt một từ khóa cung cấp cho bạn tên miền. Hoặc tôi có thể có một giá trị mặc định. Và câu hỏi đặt ra là, điều gì tạo nên một sự mặc định hợp lý? Và tôi có xu hướng làm những gì ít nguy hiểm nhất.
Vì vậy, công khai sẽ là một điều thực sự tồi tệ nếu để mặc định. Riêng tư có lẽ sẽ là một điều tồi tệ khi đặt mặc định, nếu chỉ vì mọi người thực sự không viết các phương thức riêng tư thường xuyên. Và điều tương tự với được bảo vệ. Và khi xem xét một loạt mã mà tôi có, tôi quyết định rằng thứ phổ biến nhất mà an toàn hợp lý nằm trong gói. Và C ++ không có từ khóa cho điều đó, bởi vì chúng không có khái niệm về gói.
Nhưng tôi thích nó hơn là khái niệm bạn bè, vì với bạn bè, bạn phải liệt kê tất cả bạn bè của mình là ai, và vì vậy nếu bạn thêm một lớp mới vào một gói, thì bạn thường phải đi đến tất cả các lớp học trong gói đó và cập nhật cho bạn bè của họ, điều mà tôi luôn thấy là hoàn toàn đau đớn ở mông.
Nhưng bản thân danh sách bạn bè gây ra một loại vấn đề lập phiên bản. Và vì vậy đã có khái niệm về một lớp học thân thiện. Và điều tuyệt vời là tôi đã đặt nó làm mặc định - tôi sẽ giải quyết vấn đề, vậy từ khóa nên là gì?
Trong một thời gian thực sự có một từ khóa thân thiện. Nhưng vì tất cả các từ khác đều bắt đầu bằng "P" nên nó là "dễ thương" với "PH." Nhưng điều đó chỉ ở đó có lẽ trong một ngày.
Cập nhật cách sử dụng từ khóa trong Java 8default
: Như nhiều người khác đã lưu ý Khả năng hiển thị mặc định (không có từ khóa)
trường sẽ có thể truy cập từ bên trong cùng một gói mà lớp thuộc về.
Đừng nhầm lẫn với tính năng Java 8 mới ( Phương thức mặc định ) cho phép một giao diện cung cấp triển khai khi nó được gắn nhãn với default
từ khóa.
Xem: Công cụ sửa đổi quyền truy cập
Có một công cụ sửa đổi truy cập được gọi là "mặc định" trong JAVA, cho phép tạo phiên bản trực tiếp của thực thể đó chỉ trong gói đó.
Đây là một liên kết hữu ích:
Trước hết, hãy để tôi nói một điều rằng không có thuật ngữ như "Access specifier" trong java. Chúng ta nên gọi mọi thứ là "Modifier". Như chúng ta biết rằng cuối cùng, tĩnh, đồng bộ hóa, bay hơi .... được gọi là bổ ngữ, ngay cả Công khai, riêng tư, bảo vệ, mặc định, trừu tượng cũng được gọi là bổ ngữ. Mặc định là một bổ ngữ như vậy mà sự tồn tại vật lý không có ở đó nhưng không có bổ trợ nào được đặt thì nó sẽ được coi là bổ ngữ mặc định.
Để biện minh cho điều này, hãy lấy một ví dụ:
public class Simple{
public static void main(String args[]){
System.out.println("Hello Java");
}
}
Đầu ra sẽ là: Hello Java
Bây giờ hãy thay đổi công khai thành riêng tư và xem bạn gặp lỗi trình biên dịch nào: Nó cho biết "Modifier private is not allow here" Kết luận ai đó có thể sai hoặc một số hướng dẫn có thể sai nhưng trình biên dịch không thể sai. Vì vậy, chúng ta có thể nói rằng không có thuật ngữ chỉ định truy cập trong java mọi thứ đều là bổ ngữ.