Я не був у ситуації, коли помилка компілятора, викликана цими ключовими словами, врятувала б мене від помилки.
Врятувати авторів програм від помилок не стільки, скільки авторам бібліотеки вирішувати, які частини їхньої реалізації вони зобов’язуються підтримувати.
Якщо у мене є бібліотека
class C {
public void foo() { ... }
private void fooHelper() { /* lots of complex code */ }
}
Можливо, я захочу мати можливість замінити foo
реалізацію і, можливо, змінити fooHelper
радикальними способами. Якщо група людей вирішила використовувати, fooHelper
незважаючи на всі попередження в моїй документації, я, можливо, не зможу цього зробити.
private
дозволяє авторам бібліотеки розбивати бібліотеки на керовані за розміром методи (і private
допоміжні класи), не боячись, що вони будуть змушені зберігати ці внутрішні деталі роками.
Що було б корисно для компілятора, щоб забезпечити приховування інформації?
З іншого боку, у Java private
не застосовується компілятор, а перевіряючий байт-код Java .
Чи може відображення перекрити цей механізм? Що було б корисно для компілятора, щоб забезпечити приховування інформації?
У Java не лише рефлексія може перекрити цей механізм. Є два види private
Java. Вид, private
який заважає одному зовнішньому класу отримати доступ до private
членів іншого зовнішнього класу, що перевіряється верифікатором байт-коду, а також private
s, які використовуються внутрішнім класом методом синтетичного аксесуара-приватного пакета, як у
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
класу, і не потребує перегляду будь-якого іншого коду. Отже, для перевірки цього властивості потрібні лише локальні міркування щодо коду журналу.