Несмотря на это, мне нужно, чтобы мой внутренний класс был нестатическим, потому что каждый его экземпляр должен вызывать нестатические методы, которые используют его нестатические данные экземпляра.
В этом случае, внешние объекты не должны быть мусора ... потому что внешние объекты, где находится, что данные экземпляра!
Followup
Что бы вы порекомендовали тогда? Я понятия не имею, как использовать пакеты, но мне нужно создать экземпляры Inner, которые имеют общедоступные поля данных, доступные только Outer
, и могут выжить после уничтожения Outer
. Мне повезло?
Перед тем, как ответить на ваш вопрос:
- «Я понятия не имею, как использовать пакеты ...» - вы должны узнать о них потом. Пакеты и доступ к частным пакетам являются важной частью языка Java.
Теперь на ваш вопрос ...
Если вы хотите поля только быть доступными для Outer
класса (и классов, вложенных в), то вы должны использования вложенного или внутренние классы. (Если вы попытаетесь сделать это с помощью пакета и частного доступа к пакету, тогда другие классы, объявленные в одном пакете, также смогут получить доступ к полям.. Однако, если это приемлемо, то пакеты более простой способ сделать это)
Предполагая, что вы собираетесь сделать это, используя вложенные или внутренние классы, то есть два способа сделать это:
Если вы объявите Inner
классом как private static class Inner
, то методы класса Inner
НЕ МОЖЕТ вызвать методы экземпляра или получить доступ к полям экземпляра Outer
... если у них нет ссылки и Outer
экземпляр (например, передан как параметр). Если Inner
- static
, срок службы экземпляров Inner
и Outer
являются независимыми.
Если вы объявляете Inner
класс как private class Inner
, то методы в Inner
классе могут вызывать методы экземпляра или экземпляр доступа поле Outer
. Но обратная сторона заключается в том, что время жизни экземпляра Outer
и его экземпляры Inner
теперь зависят. Конкретно, экземпляр Outer
будет существовать до тех пор, пока по крайней мере один из его экземпляров Inner
продолжает существовать. (Обратное не верно ... если экземпляр Outer
не держит ссылки на Inner
экземпляров в (скажем) в области сбора типизированных.)
Просто пересчитывать то, что я сказал ранее. Если экземпляру Inner
необходимо получить доступ к полям экземпляра или вызвать методы экземпляра на экземпляре Outer
, тогда ему требуется явная ссылка или ссылка на этот экземпляр Outer
. Это означает, что экземпляр Outer
доступен и не является кандидатом для удаления сборщиком мусора.
Другой момент - это пример Inner
, который не исчезнет, если он еще доступен; т. е. если какая-то часть вашего запущенного приложения имеет ссылку на экземпляр, который он мог бы использовать. В Java объекты НЕ получают сбор мусора, если есть любая возможность, что они могут использоваться запущенным приложением. Экземпляры внутренних/вложенных классов не являются особыми в этом отношении.
На самом деле, может быть (действительно противный!) Способ сделать это разорвать связь между Inner
и Outer
экземпляров. Если вы можете найти все экземпляры Inner
, вы можете использовать отражение, чтобы назначить null
скрытой переменной this$0
в каждой из них. Однако, если вы это сделаете, любой код в классе Inner
, который ссылается на состояние экземпляра Outer
, сломается. Если вы собираетесь прибегнуть к такой гадости, вам лучше объявить Inner
классом static
.
Как вы подтвердили, что это не GCed? – kosa
Да, этот $ 0, который я вижу в режиме Debug, все еще находится в памяти и может быть просмотрен. – user1123936
Знаете ли вы, что экземпляры не являются GC'ed, когда вы запускаете без отладчика? Возможно, их поддерживают, чтобы отладчик мог их отображать. Я нашел (как минимум, в Eclipse), что сборщик мусора часто работает в режиме отладки в режиме запуска. –