Я не був у ситуації, коли помилка компілятора, викликана цими ключовими словами, врятувала б мене від помилки.
Врятувати авторів програм від помилок не стільки, скільки авторам бібліотеки вирішувати, які частини їхньої реалізації вони зобов’язуються підтримувати.
Якщо у мене є бібліотека
class C {
public void foo() { ... }
private void fooHelper() { /* lots of complex code */ }
}
Можливо, я захочу мати можливість замінити fooреалізацію і, можливо, змінити fooHelperрадикальними способами. Якщо група людей вирішила використовувати, fooHelperнезважаючи на всі попередження в моїй документації, я, можливо, не зможу цього зробити.
privateдозволяє авторам бібліотеки розбивати бібліотеки на керовані за розміром методи (і privateдопоміжні класи), не боячись, що вони будуть змушені зберігати ці внутрішні деталі роками.
Що було б корисно для компілятора, щоб забезпечити приховування інформації?
З іншого боку, у Java privateне застосовується компілятор, а перевіряючий байт-код Java .
Чи може відображення перекрити цей механізм? Що було б корисно для компілятора, щоб забезпечити приховування інформації?
У Java не лише рефлексія може перекрити цей механізм. Є два види privateJava. Вид, privateякий заважає одному зовнішньому класу отримати доступ до privateчленів іншого зовнішнього класу, що перевіряється верифікатором байт-коду, а також privates, які використовуються внутрішнім класом методом синтетичного аксесуара-приватного пакета, як у
public class C {
private int i = 42;
public class B {
public void incr() { ++i; }
}
}
Оскільки клас B(дійсно названий C$B) використовує i, компілятор створює метод синтетичного аксесуара, який дозволяє Bотримувати доступ C.iтаким чином, що проходить повну перевірку байт-коду. На жаль, оскільки ClassLoaderдозволяє створити клас з "a" byte[], досить просто потрапити на приватних осіб, які Cзазнали впливу внутрішніх класів, створивши новий клас у Cпакеті s, який можливий, якщо Cбанку не запечатана.
Правильне privateвиконання вимагає координації між завантажувачами класів, перевіряючим байт-кодом та політикою безпеки, яка може перешкоджати рефлексивному доступу до приватних осіб.
Чи можна його використовувати для захисту таємного стану класу від нападу?
Так. "Безпечне розкладання" можливе, коли програмісти можуть співпрацювати, зберігаючи властивості захисту своїх модулів - мені не доведеться довіряти автору іншого модуля коду, щоб не порушувати властивості захисту мого модуля.
Мови об'єктних можливостей, такі як Joe-E, використовують приховування інформації та інші засоби для можливого безпечного розкладання:
Joe-E - це підмножина мови програмування Java, розроблена для підтримки захищеного програмування відповідно до дисципліни, що відповідає можливостям об'єкта. Joe-E призначений для полегшення побудови захищених систем, а також для огляду безпеки систем, вбудованих в Joe-E.
Документ, на якому посилається ця сторінка, наводить приклад того, як privateпримусове виконання робить можливим безпечне розкладання.
Забезпечення безпечної інкапсуляції.
Малюнок 1. Додаток для ведення журналу лише для додавання.
public final class Log {
private final StringBuilder content;
public Log() {
content = new StringBuilder();
}
public void write(String s) {
content.append(s);
}
}
Розглянемо рис. 1, який ілюструє, як можна побудувати об'єкт журналу, що додається. За умови, що інша частина програми написана на Joe-E, переглядач коду може бути впевнений, що записи журналу можна додавати лише та не можуть бути змінені або видалені. Цей огляд практичний, оскільки вимагає лише перевірки Log
класу, і не потребує перегляду будь-якого іншого коду. Отже, для перевірки цього властивості потрібні лише локальні міркування щодо коду журналу.