Частный класс пакета в файле .java - почему он доступен?

Рассмотрим следующий код, где класс HelloWorld имеет доступ по умолчанию или пакетный доступ:

class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!"); // Display the string.
    }
}

И предположим, что приведенный выше код сохранен в файле с именем HelloWorld.java. Итак, мой вопрос: поскольку HelloWorld теперь является частным классом пакета, как он работает? Метод main() не должен быть виден или доступен между пакетами, я прав?

Для меня имеет смысл, если класс HelloWorld объявлен общедоступным. Путаница возникает только тогда, когда он объявлен с пакетным доступом по умолчанию.


person anon1981    schedule 03.10.2011    source источник
comment
возможный дубликат Java-компиляции файла .java без общедоступный класс   -  person Qwerky    schedule 03.10.2011


Ответы (4)


Запуск JVM описан в §12.1 Запуск виртуальной машины JLS.

Обратите внимание, что в этой главе ничего не говорится о проверках видимости в отношении класса. Он только указывает, что main метод должен быть public.

Это означает, что просто нет проверки видимости на уровне класса (какой вид имеет смысл, поскольку еще нет контекста, по которому можно было бы проверить видимость: в каком «пакете» находится «вызывающий»?).

person Joachim Sauer    schedule 03.10.2011

Основной метод не будет виден другим классам, находящимся в других пакетах. Но JVM все это видит. Не составит труда найти ваш основной метод и запустить его для вас.

Если вы хотите имитировать ограничение доступа, напишите другой класс в другом пакете и попробуйте вызвать HelloWorld.main и посмотреть, молчит ли компилятор.

person adarshr    schedule 03.10.2011
comment
› Но JVM все видит. Не составит труда найти ваш основной метод и запустить его для вас. Почему? Является ли это особым свойством основного метода? - person anon1981; 03.10.2011

Вы не очень ясно выразились, но я предполагаю, что ваш вопрос заключается в том, почему этот основной метод может быть запущен, когда вы вводите java HelloWorld в командной строке.

Ответ заключается в том, что Спецификация языка Java просто не требует, чтобы класс, содержащий основной метод, был общедоступным. Модификаторы доступа — это языковой механизм, в основном предназначенный для облегчения сопровождения посредством инкапсуляции. На самом деле они не являются функцией безопасности и уж точно не являются незыблемыми законами физики. Механизм запуска JVM их просто игнорирует.

На самом деле, вы даже можете использовать закрытый внутренний класс, и он все равно будет работать.

person Michael Borgwardt    schedule 03.10.2011

Вероятно, разработчики JLS решили, что не нужно ограничивать доступ к основному методу, если вы знаете имя класса, хотя на первый взгляд это выглядит нелогично; с другой стороны - доступ всегда можно получить через отражение, поэтому его нельзя рассматривать как дыру в безопасности... Во всяком случае, например. создавая фасад для класса package-private, мы косвенно получаем к нему доступ... Таким образом, защита скорее от неправильного использования и позволяет вносить дальнейшие изменения.

person leokom    schedule 02.06.2012