Несколько классов в одном файле: модификатор private не разрешен здесь

Я не могу понять, почему этот код не компилируется:

class A {
    public static void main(String[] args) {
        System.out.println("hi");
    }
}

private class B {
    int a;
}

Я сохраняю содержимое в файле с именем A.java - и получаю сообщение об ошибке:

modifier private not allowed here // where I have defined class B

Это происходит, когда я пытаюсь использовать B как закрытый и защищенный. Может кто-нибудь объяснить мне причину этого?

Спасибо!

Ответ 1

Из Спецификация Java Language:

Модификаторы доступа, защищенные и закрытые, относятся только к классам-членам в объявлении с непосредственным объявлением класса

Так что да, частные и защищенные модификаторы не разрешены для объявлений класса верхнего уровня.

Классы верхнего уровня могут быть общедоступными или нет, а private и protected недопустимы. Если класс объявлен общедоступным, то его можно отнести к любому пакету. В противном случае его можно отнести только к одному и тому же пакету (пространство имен).

Частный класс верхнего уровня не имеет большого смысла, потому что он не может быть отнесен ни к одному классу. По определению это было бы непригодным. private ОК для классов-членов, чтобы класс, относящийся только к этому классу.

Защищенный класс-член может быть отнесен к (1) любому классу того же пакета и из (2) любого подкласса охватывающего класса. Сопоставление этой концепции с классами верхнего уровня сложно. Первый случай покрывается классом верхнего уровня без модификаторов доступа. Второй случай не применим для классов верхнего уровня, потому что нет закрывающего класса или чего-то другого из другого пакета со специальным отношением к этому классу (например, подкласса). Из-за этого я думаю, что protected не допускается, поскольку базовая концепция не применима для классов верхнего уровня.

Ответ 2

Сделайте B вложенным в A, например:

class A {
    public static void main(String[] args) {
        System.out.println("hi");
    }

    private class B {
        int a;
    }
}

Или переместите B в отдельный файл. Также вы можете придерживаться уровня доступа по умолчанию, таким образом, к классу можно получить доступ только изнутри пакета:

class A {
    public static void main(String[] args) {
        System.out.println("hi");
    } 
}

class B {
    int a;
}

Ответ 3

частные и защищенные бессмысленно допускать класс/интерфейс верхнего уровня (не член).

Они применимы только к членам класса, которые могут быть переменными, константами, конструкторами, методами, классами и интерфейсами.

Почему:

(1) private: Что может быть значением/целью, если мы определяем класс как закрытый. Его область должна быть частной для некоторых областей. доступ по умолчанию уже является приватным пакетом. И никто не хочет, чтобы класс был закрытым исходным файлом (возможно, это объясняется), возможно, это не хорошая практика программирования, потому что Java-приложения, наконец, организованы в виде пакетов, но не в терминах исходных файлов. Любой исходный файл должен быть частью некоторого пакета, поэтому в широком/конечном представлении каждый класс/интерфейс является частью некоторого пакета, а не только некоторого .java файла. Поэтому неприменимо.

(2) protected. Если что-то защищено, оно должно быть доступно только внутри пакета и только для подклассов в других пакетах. Чтобы расширить класс в другом пакете, он должен быть доступен для всех классов в других пакетах, но protected говорит, что класс должен быть доступен только для расширенных классов. Это своего рода тупиковая ситуация. Поэтому неприменимо.

Источник: мои чтения и понимание

Ответ 4

Просто не имеет частного/защищенного модификатора.

Ответ 5

B должен быть закрыт для чего-то. Поместите его в определение класса A или создайте другой файл B.java и определите его там, но тогда он не может быть закрытым.

Ответ 6

Если вы не используете общедоступное ключевое слово для класса, оно будет закрыто по умолчанию (видимо только внутри файла).

В файле .java может быть только один открытый класс, все остальные должны быть закрытыми. Таким образом, класс A может быть общедоступным, а класс B не нуждается в модификаторах в вашем примере. Имя открытого класса должно соответствовать имени файла .java(например, A.java может содержать только один открытый класс под названием "A" ).

Ответ 7

A.java не может содержать два класса.