Що таке специфікатор доступу за замовчуванням у Java?


108

Я щойно почав читати книгу Java і задумався; який специфікатор доступу є типовим, якщо він не вказаний?


Правильний термін - "модифікатор доступу". Слово "специфікатор" не відображається в JLS.
Маркіз Лорн

Відповіді:


116

Видимість за замовчуванням відома як "package-private" (хоча ви не можете використовувати це явно), що означає, що поле буде доступне всередині того ж пакету, до якого належить клас.

Як зазначає mdma, це неправда для членів інтерфейсу, для яких за замовчуванням є "public".

Див . Специфікації доступу Java


25
неправильно - не вірно для членів інтерфейсу. доступ за замовчуванням тоді публічний
mdma

2
Насправді він відомий як "приватний пакет". Сторонні веб-сайти не є нормативними посиланнями. Ви повинні цитувати лише JLS.
Маркіз Лорн

81

Специфікатор за замовчуванням залежить від контексту.

Для класів та інтерфейсів оголошень за замовчуванням є приватний пакет. Це розділяється між захищеним та приватним, дозволяючи лише класам в одному пакеті доступу. (захищено таким чином, але також дозволяє отримати доступ до підкласів поза пакетом.)

class MyClass   // package private
{
   int field;    // package private field

   void calc() {  // package private method

   }
}

Для учасників інтерфейсу (поля та методи) доступ за замовчуванням є загальнодоступним. Але зауважте, що сама заява інтерфейсу за замовчуванням застосовується до приватного пакету.

interface MyInterface  // package private
{
   int field1;         // static final public

   void method1();     // public abstract
}

Якщо ми тоді маємо декларацію

public interface MyInterface2 extends MyInterface
{

}

Класи, що використовують MyInterface2, можуть бачити field1 та method1 із суперінтерфейсу, оскільки вони є загальнодоступними, хоча вони не бачать декларації самого MyInterface.


1
"Пакет приватний" (іноді написаний у джерелі як /* pp */) - лише зручна назва для доступу за замовчуванням . Це не назва JLS.
Том Хотін - тайклін

10
@Tom - це правильно, JLS використовує "доступ за замовчуванням". Я міг би написати "за замовчуванням - доступ за замовчуванням". Але це не здавалося надто корисним!
mdma

16

Якщо не вказано специфікатора доступу, це доступ на рівні пакету (для цього немає явного специфікатора) для класів та членів класу. Методи інтерфейсу неявно є загальнодоступними.


9

Видимість за замовчуванням (без ключового слова) - це пакет, що означає, що він буде доступний для кожного класу, який знаходиться в одному пакеті.

Цікавою стороною є те, що захищений не обмежує видимість для підкласів, а також для інших класів того ж пакету


8

Це залежить від того, в чому річ.

  • Типи верхнього рівня (тобто класи, переліки, інтерфейси та типи приміток, не оголошені всередині іншого типу) за замовчуванням є пакетними приватними . ( JLS §6.6.1 )

  • У класах всі учасники (це означає поля, методи та вкладені декларації типу) та конструктори за замовчуванням є пакетно-приватними . ( JLS §6.6.1 )

    • Коли клас не має явно оголошеного конструктора, компілятор вставляє конструктор з нульовим аргументом за замовчуванням, який має той же специфікатор доступу, що і клас . ( JLS § 8.8.9 ) Конструктор за замовчуванням зазвичай неправильно є загальнодоступним, але в рідкісних випадках це не еквівалентно.
  • У перерахунках конструктори за замовчуванням приватні . Дійсно, споруди перерахунків повинні бути приватними, і помилково визначати їх як загальнодоступні чи захищені. Константи Enum завжди є загальнодоступними і не дозволяють отримати жодний специфікатор доступу. Інші члени перерахунків за замовчуванням є пакетними приватними . ( JLS § 8.9 )

  • У типах інтерфейсів та анотацій усі учасники (знову ж таки, це означає поля, методи та вкладені декларації типу) за замовчуванням є загальнодоступними . Дійсно, члени інтерфейсів та типів анотацій повинні бути загальнодоступними, і помилково вказати їх як приватні або захищені. ( JLS §9.3 до 9.5 )

  • Місцеві класи називають класи, оголошені всередині методу, конструктора або блоку ініціалізатора. Вони потрапляють до блоку {.., }в якому вони оголошені, і не дозволяють жодного специфікатора доступу. ( JLS §14.3 ) Використовуючи роздуми, ви можете інстанціювати локальні класи з інших місць, і вони є приватними пакетами , хоча я не впевнений, чи є ця деталь у JLS.

  • Анонімні класи - це створені спеціальні класи, за допомогою newяких визначається тіло класу безпосередньо у виразі. ( JLS §15.9.5 ) Їх синтаксис не дозволяє жодним специфікатором доступу. Використовуючи роздуми, ви можете інстанціювати анонімні класи з інших місць, і вони, і їх створені конструктори є пакетними приватними , хоча я не впевнений, чи є ця деталь в JLS.

  • Блоки екземпляра і статичний ініціалізатор не мають специфікаторів доступу на мовному рівні ( JLS §8.6 та 8.7 ), але статичні блоки ініціалізатора реалізуються як метод, названий <clinit>( JVMS §2.9 ), тому метод повинен внутрішньо мати деякий специфікатор доступу. Я вивчив класи, складені javac та компілятором Eclipse за допомогою шестигранного редактора і виявив, що обидва генерують метод як пакет-приватний . Однак ви не можете зателефонувати <clinit>()всередині мови, оскільки символи <та >символи недійсні в назві методу, а способи відображення є жорсткими, щоб заперечувати його існування, тому ефективно його специфікатором доступу немає доступу . Метод може викликати тільки ВМ під час ініціалізації класу.Блоки ініціалізаторів екземплярів не компілюються як окремі методи; їх код копіюється в кожен конструктор, тому не можна отримати доступ до них індивідуально, навіть шляхом відображення.


7

за замовчуванням - ключове слово, яке використовується як модифікатор доступу для методів та змінних.
Використання цього модифікатора доступу зробить ваш клас, змінну, метод чи конструктор доступними для власного класу чи пакету, він також буде встановлений, якщо немає модифікатора доступу.

  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

якщо ви використовуєте типовий інтерфейс, ви зможете реалізувати такий метод, як цей приклад

public interface Computer {    
    default void Start() {
        throw new UnsupportedOperationException("Error");
    }    
}

Однак він працює лише з 8 версії Java

Офіційна документація

Доступ до модифікаторів на Java


3

Дивіться тут для більш детальної інформації. За замовчуванням немає приватного / публічного / захищеного, але зовсім інша специфікація доступу. Він не використовується широко, і я вважаю за краще бути більш конкретним у своїх визначеннях доступу.


3

типовим специфікатором доступу є пакет. Класи можуть отримати доступ до членів інших класів у тому ж пакеті, але поза пакетом він виглядає як приватний


3

Ось цитата про видимість рівня пакету з інтерв'ю з Джеймсом Гослінгом, творцем Java:

Білл Веннерс : Ява має чотири рівні доступу. За замовчуванням - пакет. Я завжди цікавився, чи зробити доступ до пакету за замовчуванням зручним, оскільки три ключові слова, про які люди з C ++ вже знали, були приватними, захищеними та відкритими. Або якщо у вас була якась конкретна причина, що ви вважаєте, що доступ до пакету повинен бути типовим.

Джеймс Гослінг : Пакет - це, як правило, сукупність речей, написаних разом. Так що загалом я міг би зробити одну з двох речей. Одне було змусити вас завжди вводити ключове слово, яке дає вам домен. Або я міг мати значення за замовчуванням. І тоді питання полягає в тому, що робить розумний дефолт? І я схильний йти на те, що є найменш небезпечним.

Таким чином, громадськістю було б дійсно погано зробити дефолт. Приватним, мабуть, було б погано робити дефолт, хоча б тому, що люди насправді часто не пишуть приватні методи. І те саме з захищеними. І переглянувши купу коду, який у мене був, я вирішив, що найпоширеніша річ, яка була досить безпечною, лежить у пакеті. І у C ++ не було ключового слова для цього, оскільки вони не мали поняття про пакети.

Але мені це сподобалося, ніж поняття про друзів, тому що з друзями вам належить перерахувати, хто всі ваші друзі, і тому, якщо ви додасте новий клас до пакету, то вам, як правило, потрібно перейти до всіх заняття в цьому пакеті та оновлення своїх друзів, які я завжди вважав, що це повна біль у задці.

Але сам список друзів спричиняє певну проблему з версією. І так виникло це поняття про дружній клас. І приємна річ, що я робив це за замовчуванням - я вирішу проблему, то яким має бути ключове слово?

Деякий час насправді було дружнє ключове слово. Але оскільки всі інші починаються з "P", це було "приязно" з "PH". Але це було лише там, можливо, на день.

http://www.artima.com/intv/gosling2P.html


2

Оновіть використання ключового слова Java 8default : Як і багато інших відмітили, видимість за замовчуванням (без ключового слова)

поле буде доступне всередині того самого пакету, до якого належить клас.

Не плутати з новою функцією Java 8 ( Методи за замовчуванням ), яка дозволяє інтерфейсу забезпечувати реалізацію, коли її позначено defaultключовим словом.

Див.: Доступ до модифікаторів



-2

Насамперед дозвольте сказати одне, що у Java не існує такого терміна, як "специфікатор доступу". Ми повинні називати все як "Модифікатори". Як ми знаємо, що остаточні, статичні, синхронізовані, мінливі .... називаються модифікаторами, навіть модифікатори, навіть загальнодоступні, приватні, захищені, за замовчуванням, абстрактні також повинні називатися модифікаторами. За замовчуванням - це такі модифікатори, де фізичного існування немає, але модифікаторів не розміщено, тоді це слід розглядати як модифікатори за замовчуванням.

Для обґрунтування цього візьміть один приклад:

public class Simple{  
    public static void main(String args[]){  
     System.out.println("Hello Java");  
    }  
}  

Вихід буде: Hello Java

Тепер змініть публічне на приватне і подивіться, яку помилку компілятора ви отримаєте: Там написано "Модифікатор приватний тут не дозволений". Який висновок хтось може помилятися чи якийсь підручник може бути неправильним, але компілятор не може помилитися. Таким чином, ми можемо сказати, що в Java не існує специфікатора доступу до терміна, все є модифікаторами.


Перше речення є точковим, але той факт, що зовнішній клас не може бути приватним, не підтверджує, що в Java немає такого поняття, як специфікатор доступу.
Маркіз Лорн

@EJP Це лише приклад. Що я говорю, це те, що термін специфікатор доступу використовується в інших мовах, таких як c, крапка net тощо, але технічний термін в Java для цього є модифікаторами. Якщо ви використовуєте eclipse чи будь-який інший IDE, ви можете побачити, що під час створення нового класу нам пропонують вказати ім’я модифікаторів, а в списку вони - публічні, приватні, абстрактні тощо
Sagar Raut

У моєму прикладі те, що я намагаюся сказати, що компілятор подає повідомлення про помилку: модифікатори приватні заборонено, він не дає повідомлення, як специфікатор доступу приватний, не дозволений. Отже, технічний термін, про який слід сказати, - це модифікатори в java, які не мають специфікатора доступу в java
Sagar Raut
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.