Ответы:
Видимость по умолчанию известна как «частный пакет» (хотя вы не можете использовать это явно), что означает, что поле будет доступно из того же пакета, к которому принадлежит класс.
Как указала mdma, это неверно для членов интерфейса, для которых по умолчанию установлено значение «public».
Спецификатор по умолчанию зависит от контекста.
Для классов и объявлений интерфейсов по умолчанию используется частный пакет. Это находится между защищенным и частным, разрешая доступ только классам в одном пакете. (protected похоже на это, но также разрешает доступ к подклассам вне пакета.)
class MyClass // package private
{
int field; // package private field
void calc() { // package private method
}
}
Для членов интерфейса (полей и методов) доступ по умолчанию является открытым. Но обратите внимание, что само объявление интерфейса по умолчанию имеет значение package private.
interface MyInterface // package private
{
int field1; // static final public
void method1(); // public abstract
}
Если у нас есть декларация
public interface MyInterface2 extends MyInterface
{
}
Классы, использующие MyInterface2, могут затем видеть field1 и method1 из суперинтерфейса, поскольку они являются общедоступными, даже если они не могут видеть объявление самого MyInterface.
/* pp */
) - всего лишь удобное имя для доступа по умолчанию . Это не имя JLS.
Если спецификатор доступа не указан, это доступ на уровне пакета (для этого нет явного спецификатора) для классов и членов классов. Методы интерфейса неявно открыты.
Видимость по умолчанию (без ключевого слова) - это пакет, что означает, что он будет доступен каждому классу, который находится в том же пакете.
Интересное замечание заключается в том, что protected не ограничивает видимость подклассами, но также и другими классами в том же пакете.
Это зависит от того, что это за штука.
Типы верхнего уровня (то есть классы, перечисления, интерфейсы и типы аннотаций, не объявленные внутри другого типа) по умолчанию являются частными для пакета . ( JLS §6.6.1 )
В классах все члены (что означает поля, методы и объявления вложенных типов) и конструкторы по умолчанию являются частными для пакета . ( JLS §6.6.1 )
В перечислениях конструкторы по умолчанию являются закрытыми . Действительно, конструкторы 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>()
в языке , потому что <
и >
символы являются недопустимыми в имени метода, а также методы отражения являются жестко отрицать ее существование, поэтому эффективно его спецификатор доступа не является отсутствие доступа . Метод может быть вызван только виртуальной машиной во время инициализации класса.Блоки инициализатора экземпляра не компилируются как отдельные методы; их код копируется в каждый конструктор, поэтому к ним нельзя получить доступ по отдельности, даже путем отражения.
default - это ключевое слово, которое используется как модификатор доступа для методов и переменных.
Использование этого модификатора доступа сделает ваш класс, переменную, метод или конструктор доступными из собственного класса или пакета, он также будет установлен, если модификатор доступа отсутствует.
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:
Билл Веннерс : Java имеет четыре уровня доступа. По умолчанию это пакет. Я всегда задавался вопросом, удобно ли было сделать доступ к пакету по умолчанию, потому что три ключевых слова, о которых люди из C ++ уже знали, были частными, защищенными и общедоступными. Или если у вас была какая-то конкретная причина, по которой вы считали, что доступ к пакету должен быть по умолчанию.
Джеймс Гослинг : Пакет обычно представляет собой набор вещей, которые написаны вместе. В общем, я мог сделать одно из двух. Один из них - заставить вас всегда вводить ключевое слово, которое дает вам домен. Или у меня могло быть значение по умолчанию. И тогда возникает вопрос, что является разумным дефолтом? И я стремлюсь к наименее опасным вещам.
Так что публичное использование было бы очень плохим решением по умолчанию. Использовать частные методы по умолчанию, вероятно, было бы плохо, хотя бы потому, что люди на самом деле не так часто пишут частные методы. То же самое и с protected. И, просмотрев кучу кода, который у меня был, я решил, что самое обычное, что было достаточно безопасно, было в пакете. И в C ++ не было ключевого слова для этого, потому что у них не было понятия пакетов.
Но мне понравилось это больше, чем идея друзей, потому что с друзьями вам как бы нужно перечислять, кто все ваши друзья, и поэтому, если вы добавляете новый класс в пакет, вам обычно приходится переходить ко всем классы в этом пакете и обновляют своих друзей, что я всегда считал полной головной болью.
Но сам список друзей вызывает своего рода проблему с версией. Так возникло понятие дружеского класса. И самое приятное, что я сделал это по умолчанию - я решу проблему, так каким должно быть ключевое слово?
Некоторое время действительно существовало дружественное ключевое слово. Но поскольку все остальные начинаются с «P», это было «по-дружески» с «PH». Но это было там только на день.
Обновление использования ключевого слова в Java 8default
: как отметили многие другие, видимость по умолчанию (без ключевого слова)
поле будет доступно изнутри того же пакета, которому принадлежит класс.
Не следует путать с новой функцией Java 8 ( методы по умолчанию ), которая позволяет интерфейсу предоставлять реализацию, когда он помечен default
ключевым словом.
См .: Модификаторы доступа
В JAVA есть модификатор доступа, называемый "по умолчанию", который позволяет напрямую создавать экземпляры этой сущности только внутри этого пакета.
Вот полезная ссылка:
Прежде всего позвольте мне сказать, что в java нет такого термина, как "спецификатор доступа". Мы должны называть все «Модификаторами». Как мы знаем, final, static, synchronized, volatile .... называются модификаторами, даже Public, private, protected, default, abstract также должны называться модификаторами. По умолчанию это такие модификаторы, в которых физическое существование отсутствует, но модификаторы не размещены, тогда их следует рассматривать как модификаторы по умолчанию.
Чтобы обосновать это, возьмем один пример:
public class Simple{
public static void main(String args[]){
System.out.println("Hello Java");
}
}
Результат будет: Hello Java
Теперь измените общедоступный на частный и посмотрите, какую ошибку компилятора вы получите: здесь говорится: «Приватный модификатор здесь не разрешен». Каков вывод: кто-то может ошибаться или какой-то учебник может быть неправильным, но компилятор не может ошибаться. Таким образом, мы можем сказать, что в java нет спецификатора доступа к терминам, все есть модификаторами.