Недавно группа безопасности в моем проекте выпустила документ с рекомендациями по безопасному коду, предназначенный для использования в рамках наших обзоров кода. Первое, что меня поразило, это предмет, который сказал "Не использовать внутренние классы". Я подумал, что это похоже на очень тяжелое рутинное выражение. Внутренние классы хороши, если их правильно использовать правильно, но я немного поработал с поиском и нашел этот, приведенный здесь для удобства.
Правило 5: Не используйте внутренние классы
Некоторые книги на Java говорят, что к внутренним классам можно получить доступ только внешние классы, которые их охватывают. Это неправда. Байт Java-кода имеет нет понятия внутренних классов, поэтому внутренние классы переводятся компилятором в обычные классы, которые происходят с быть доступным для любого кода в том же пакет. Правило 4 говорит, что не зависеть на упаковке для защиты.
Но подождите, все становится хуже. Внутренний класс получает доступ к полям охватывающий внешний класс, даже если эти поля объявляются закрытыми. И внутренний класс переводится в отдельный класс. Чтобы это разрешить отдельный доступ класса к полям внешний класс, компилятор молча изменяет эти поля от частного до область упаковки! Это плохо, что внутренний класс разоблачен, но это еще хуже, что компилятор тихо отменяя ваше решение сделать некоторые поля частными. Не использовать если вы можете это сделать. (По иронии судьбы, новая Java 2 doPrivileged() API предположим, что вы используете внутренний класс для пишите привилегированный код. Вон тот причина, по которой нам не нравится doPrivileged().)
Мои вопросы
- Сохраняется ли такое поведение в java 5/6?
- Является ли это на самом деле угрозой безопасности, учитывая, что какой-либо класс, кроме внешних и внутренних классов, пытающихся получить доступ к закрытым членам внешнего класса, не будет компилироваться?
- Означает ли он достаточный риск для безопасности, чтобы подтвердить "рекомендацию" "Не использовать внутренние классы"?