Третя частина відповідей і питань для співбесіди з ООП в Java.
Питання. частина 3
Відповіді. частина 3
43. Яким чином можна звернутися до локальної змінної методу з анонімного класу, оголошеного в тілі цього методу? Чи є які-небудь обмеження для такої змінної?
Також як і локальні класи, анонімні можуть захоплювати змінні, доступ до локальних змінних відбувається за тими ж правилами:
Анонімні класи також можуть містити в собі локальні класи. Конструктора в анонімному класі бути не може.
44. Як пов'язаний будь-який користувацький клас з класом Object?
Всі класи є спадкоємцями суперкласу Object. Це не потрібно вказувати явно. В результаті об'єкт Object o може посилатися на об'єкт будь-якого іншого класу.
- public final native Class getClass () - повертає в Рантайм клас даного об'єкта.
- public native int hashCode () - повертає хеш-код
- public boolean equals (Object obj) - порівнює об'єкти.
- protected native Object clone () throws CloneNotSupportedException - клонування об'єкта
- public String toString () - повертає строкове представлення об'єкту.
- public final native void notify () - прокидається один потік, який чекає на "моніторі" даного об'єкта.
- public final native void notifyAll () - прокидаються всі потоки, які чекають на "моніторі" даного об'єкта.
- public final native void wait (long timeout) throws InterruptedException - потік переходить в режим очікування протягом зазначеного часу.
- public final void wait () throws InterruptedException - наводить даний потік в очікування, поки інший потік не викличе notify () або notifyAll () методи для цього об'єкта.
- public final void wait (long timeout, int nanos) throws InterruptedException - наводить даний потік в очікування, поки інший потік не викличе notify () або notifyAll () для цього методу, або поки не закінчиться зазначений проміжок часу.
- protected void finalize () throws Throwable - викликається збирачем сміття, коли garbage collector визначив, що посилань на об'єкт більше немає.
46. Що таке метод equals (). Чим він відрізняється від операції ==.
47. Якщо ви хочете перевизначити equals (), які умови повинні задовольнятися для перевизначеного методу?
47. Якщо equals () перевизначений, чи є які-небудь інші методи, які слід перевизначити?
49. У чому особливість роботи методів hashCode і equals? Яким чином реалізовані методи hashCode і equals в класі Object? Які правила і угоди існують для реалізації цих методів? Коли вони застосовуються?
- Рефлексивність. для будь-якого ненульового x, x.equals (x) поверне true;
- Транзитивність. для будь-якого ненульового x, y і z, якщо x.equals (y) і y.equals (z) поверне true, тоді і x.equals (z) поверне true;
- Симетричність: для будь-якого ненульового x і y, x.equals (y) має повернути true, тоді і тільки тоді, коли y.equals (x) поверне true.
- Також для будь-якого ненульового x, x.equals (null) має повернути false
При перевизначенні equals () обов'язково потрібно перевизначити метод hashCode (). Рівні об'єкти повинні повертати однакові хеш коди.
Хеш-код - це число. Якщо точніше, то це бітова рядок фіксованої довжини, отримана з масиву довільної довжини. У термінах Java, хеш-код - це цілочисельний результат роботи методу, якому в якості вхідного параметра переданий об'єкт.
Цей метод реалізований таким чином, що для одного і того-ж вхідного об'єкта, хеш-код завжди буде однаковим. Слід розуміти, що безліч можливих хеш-кодів обмежена примітивним типом int. а безліч об'єктів обмежена тільки нашої фантазією. Звідси випливає твердження: "Безліч об'єктів могутніше безлічі хеш-кодів". Через це обмеження, цілком можлива ситуація, що хеш-коди різних об'єктів можуть збігтися.
Тут головне зрозуміти, що:
- Якщо хеш-коди різні, то і вхідні об'єкти гарантовано різні.
- Якщо хеш-коди рівні, то вхідні об'єкти не завжди рівні.
Ситуація, коли у різних об'єктів однакові хеш-коди називається - колізією. Імовірність виникнення колізії залежить від використовуваного алгоритму генерації хеш-коду.
50. Який метод повертає строкове представлення об'єкту?
51. Що буде, якщо перевизначити equals НЕ перевизначаючи hashCode? Які можуть виникнути проблеми?
Порушиться контракт. Класи і методи, які використовували правила цього контракту можуть функціонувати належним чином. Так для об'єкта HashMap це може привести до того, що пара, яка була поміщена в Map можливо не буде знайдена в ній при зверненні до Map, якщо використовується новий екземпляр ключа.
52. Чи є які-небудь рекомендації про те, які поля слід використовувати при підрахунку hashCode?
Ті, які використовують при визначенні методу equals (). Хеш код повинен бути рівномірно розподілений на області можливих прийнятих значень.
53. Як ви думаєте, чи будуть якісь проблеми, якщо в об'єкта, який використовується в якості ключа в hashMap зміниться поле, яке бере участь у визначенні hashCode?
Будуть. При зверненні по ключу ми можемо не знайти значення.
54. Чим відрізняється абстрактний клас від інтерфейсу, в яких випадках що ви будете використовувати?
Абстрактні класи використовуються тільки тоді, коли є «is a» тип відносин; інтерфейси можуть бути реалізовані класами які не пов'язані один з одним.
Абстрактний клас може реалізовувати методи; інтерфейс може реалізовувати статичні методи і починаючи з 8й версії.
Інтерфейс може описувати константи і методи. Всі методи інтерфейсу за замовчуванням є публічними (public) і абстрактними (abstract), а поля - public static final. З java 8 в інтерфейсах можна реалізовувати default і статичні методи.
В Java клас може успадковуватися (реалізовувати) від багатьох інтерфейсів, але тільки від одного абстрактного класу.
З абстрактними класами ви втрачаєте індивідуальність класу, що посяде його; з інтерфейсами ви просто розширюєте функціональність кожного класу.
55. Чи можна отримати доступ до private змінних класу і якщо так, то яким чином?
56. Що таке volatile і transient? Для чого і в яких випадках можна було б використовувати default?
volatile - не використовується кеш (мається на увазі область пам'яті в якій JVM може зберігати локальну копію змінної, щоб зменшити час звернення до змінної) при зверненні до полю. Для volatile змінної JVM гарантує синхронізацію для операцій читання / запису, але не гарантує для операцій зміни значення змінної.
transient - вказівка того, що при серіалізациі / десеріалізациі дане поле не потрібно серіалізовать / десеріалізовивать.
57. Розширення модифікаторів при спадкуванні, перевизначення і приховування методів. Якщо у класу-батька є метод, оголошений як private, чи може спадкоємець розширити його видимість? А якщо protected? А звузити видимість?
Діє загальний принцип: розширювати видимість можна, звужувати не можна. private методи видно тільки всередині класу, для нащадків вони не видно. Тому їх і розширити не можна.
58. Чи має сенс оголошувати метод private final?
Ні, такий метод і так не видно для спадкоємців, а значить не може бути ними перевизначений.
59. Які особливості ініціалізації final змінних?
- Для поля. Поле позначене за допомогою слова final не може змінити своє значення після ініціалізації.
Чи не статичне final поле можна форматувати: при описі, в конструкторі (у всіх), в статичному блоці, в динамічному блоці.
Статична final поле (static final) инициализируется або в статичному блоці, або при описі. - Значення локальних змінних, а так же параметрів методу помічених за допомогою слова final не можуть бути змінені після присвоєння.
60. Що буде, якщо єдиний конструктор класу оголошений як final?
До конструктору не застосовується ключове слово final.
61. Що таке finalize? Навіщо він потрібен? Що Ви можете розповісти про збирача сміття і алгоритмах його роботи.
Метод finalize () викликається перед тим, як об'єкт буде видалений garbage collector (збирач сміття, далі gc). Існує багато різних реалізацій gc. Основа роботи наступна, gc позначає об'єкти, на які більше не посилаються інші об'єкти для їх видалення. Потім на одному з проходів помічені об'єкти видаляються.
Виклик finalize () не гарантовано, тому що додаток може бути завершено до того, як буде запущена ще одна збірка сміття. Так, можна скасувати збірку об'єкта за допомогою методу finalize (). присвоївши його посилання якомусь статистичному методу.
62. Чому метод clone оголошений як protected? Що необхідно для реалізації клонування?
Це вказує на те, що хоч метод і є в класі Object і розробник бажає їм скористатися, то його потрібно перевизначити. Для цього потрібно реалізувати інтерфейс Clonable. щоб дотримати контракт.
59. Які особливості ініціалізації final змінних?
Для поля. Поле позначене за допомогою слова final не може змінити своє значення після ініціалізації (инициализируется або при описі, або в конструкторі / статичному блоці).
- Якщо final без static то АБО в динамічному блоці, АБО у ВСІХ конструкторах, АБО при описі.
-Якщо final static то то АБО в статичному блоці, АБО при описі, АБО за замовчуванням.
Розділив відповідь на static \ Не static і дописав про все конструктори. За замовчуванням final static int a; НЕ скомпілюється на 0.
volatile - не використовується кеш (мається на увазі область пам'яті в якій JVM може зберігати локальну копію змінної, щоб зменшити час звернення до змінної) при зверненні до полю
- це неповний відповідь
Для volatile змінної JVM гарантує синхронізацію для операцій читання / запису, але не гарантує для операцій зміни значення змінної
І ця відповідь теж не повний. Нутрощі роботи з кешем проца і java машиною явно не влізуть в цей розділ. Але все одно додав, спасибі.