Java: частные внутренние классы возвращаются во внешний код
Я только недавно начал изучать Java, исходя из C# фона.
Когда я начал использовать Коллекции, я заметил, что Arrays.asList() возвращает ArrayList<T>
объект.
Что я не понимаю, так это то, что согласно списку кода в ' docjar' (строка 2834) метки ArrayList<T>
как личное.
Как я могу использовать объект, который был явно помечен как скрытый от меня? Или (и это то, что я подозреваю), частное имеет какое-то значение, отличное от того, которое я предполагаю?
(Также отмечу, что этот класс помечен как статический, что также смущает меня, но я спрошу об этом в отдельном вопросе)
Редактировать: пример в C#, который выдает ошибку компилятора:
public class PubClass {
private class Blah {
}
public Blah GetBlah() {
return new Blah();
}
}
Дает: Непоследовательная доступность: тип возвращаемого значения "Namespace.PubClass.Blah" менее доступен, чем метод "Namespace.PubClass.GetBlah()"
3 ответа
ArrayList
что вам вернули List
и все методы, содержащиеся в этом интерфейсе. поскольку List
является общедоступным, вы знаете об этих методах и можете вызывать их.
Причина того, что ArrayList
является частным, потому что нет никаких причин для его публичности: он не предоставляет никаких дополнительных функций, кроме List
Интерфейс обеспечивает.
/редактировать
Ваш пример не подражает тому, что здесь происходит:
public interface List<T> {
/** snip */
}
public class Arrays {
private static class ArrayList<T> implements List<T> {
/** snip */
}
public <T> List<T> asList(T... arr) {
return new ArrayList<>(arr);
}
}
В вашем примере вы пытаетесь вернуть экземпляр закрытого класса, о котором внешний вызывающий не знает. в Arrays
Например, возвращаемый объект на самом деле List
(посмотрите на тип возвращаемого значения), а не частный ArrayList
,
Приватный означает, что класс / поле / метод, помеченный как закрытый, доступен только в текущей области - классе, в котором он определен. Это означает, что вы извне не можете создать новый ArrayList, как указано в классе Arrays. Тем не менее, члены в классе могут использовать класс, так как asList(T... a)
метод делает.
Тип возвращаемого значения на самом деле List<T>
суперкласс ArrayList<T>
, так что вы можете использовать его как открытый класс с методами, известными вашей программе.
Класс помечен как статический, потому что он не должен быть динамическим; определение класса не меняется с каждым новым экземпляром Arrays
,
Приватный просто означает, что он не доступен вне класса через его интерфейс. Например, вы не можете сделать что-то вроде: myObject.m_privateVariable
, Все, что произошло, это asList
'getter' возвращает ссылку на приватную переменную, поэтому выставляет ее контролируемым образом.
Использование методов доступа (см. Методы мутатора) позволяет классу контролировать доступ к этим данным. Например, вы можете выполнить некоторую операцию с закрытой переменной перед ее возвратом, что вы не смогли бы сделать за один вызов, если бы у мира был прямой доступ ко всем переменным-членам.