Чи погана практика створювати нові об’єкти, не зберігаючи їх?


23

Я бачив об’єкти, створені в коді Java, не зберігаючи посилання на об'єкт. Наприклад, у плагіні затемнення я бачив SWT-оболонку, створену так:

new Shell();

Цей новий об'єкт Shell не зберігається у змінній, але залишатиметься посиланням до тих пір, поки не буде розміщено вікно, яке [я вважаю?] Відбувається за замовчуванням, коли вікно закриється.

Чи погана практика створювати подібні об’єкти, не зберігаючи посилання на них? Або бібліотека була погано оформлена? Що робити, якщо я не потребую посилання, а хочу лише "побічні ефекти" об'єкта? Чи потрібно зберігати посилання в будь-якому випадку?

ОНОВЛЕННЯ:

Звичайно, мій приклад є поганим. Хоча я бачив елементи інтерфейсу, створені таким чином, створення SWT-оболонки, подібної до цього, мабуть, буде безглуздим, оскільки вам потрібно викликати відкритий метод в екземплярі Shell. Існують кращі приклади, подані в aix, такі, як наведено нижче в навчальному посібнику з кон'юнктури Java :

(new HelloThread()).start();

Така практика спостерігається у багатьох контекстах, тому питання залишається. Це хороша практика?


2
Який би був сенс зберігання довідки?
Даніель Р Хікс

(З концептуальної точки зору, мабуть, було б краще стати статичним методом, таким як Shell.createTopLevelShell()чи що завгодно, проти використання конструктора в цьому випадку. Але функціонально немає різниці.)
Даніель Р Хікс

Це питання щодо практики створення об'єктів без посилань на них, створення класів, які вимагають цієї практики, чи це конкретно про те, як SWT використовує подібний зразок?
Стриптинг-воїн

1
Об'єктами SWT повинно бути dispose()d: Правило 1: Якщо ви створили його, ви розпоряджаєтесь ним. eclipse.org/articles/swt-design-2/swt-design-2.html
jbindel

2
Я б використовував змінну для проведення посилання для цілей налагодження. Якщо у вас є точка перерви в цьому методі, ви можете отримати відладчик для запиту об'єкта через локальну змінну. Без посилання я впевнений, що це можливо, але, мабуть, набагато складніше.
Мартін Йорк

Відповіді:


12

У цьому є елемент особистої переваги, але я думаю, що не зберігати посилання - це не обов'язково погана практика.

Розглянемо наступний гіпотетичний приклад:

new SingleFileProcessor().process(file);

Якщо для кожного файлу потрібно створити новий об’єкт процесора, який не потрібен після process()виклику, зберігати посилання на нього немає сенсу.

Ось ще один приклад, взятий з навчального посібника з спільної роботи Java :

(new HelloThread()).start();

Я бачив безліч інших прикладів, коли посилання не зберігається, і це читається мені прекрасно, наприклад:

String str = new StringBuilder().append(x).append(y).append(z).toString();

( StringBuilderОб'єкт не зберігається.)

Існують подібні зразки за участю common.lang's HashCodeBuilderet al.


2
@BalusC: Щодо поваги, я не бачу, що робить це рибним і яким способом краще мати заводський метод (я припускаю, що ваш приклад є аналогічним моєму, і getInstance()це фабрика, а не сингл).
NPE

Залежно від того, використовувати одноразовий чи ні. Абонент заводу не повинен надто думати про це.
Дональні стипендіати

У вашому прикладі екземпляр FileProcessor (імовірно) не потрібен після завершення оператора, тоді як у прикладі ОП екземпляр Shell (під обкладинками) посилається на інший об'єкт, і це посилання (і, отже, об'єкт Shell) зберігається поза межами тривалість заяви.
Даніель Р Хікс

@BalusC: FileProcessor може мати додаткові методи зміни поведінки process.
кевін клайн

7

Якщо вам не потрібна посилання на створений об'єкт, тоді не тримайтеся за посилання. Це так просто.


5

Взагалі, це найкраща практика випускати посилання настільки швидко, наскільки вони можуть бути розумно випущені. Я не бачу різниці між:

HelloThread thread = new HelloThread();
thread.start();
// where thread is never used for the rest of the method

і

(new HelloThread()).start();

Що стосується коду, ви просто уникаєте використання імені змінної, що може бути позитивною справою. Компілятор JIT, як правило, досить розумний, щоб визнати, що він може зібрати сміття після останнього використання, тому, мабуть, немає різниці з точки зору продуктивності.

Єдине справжнє питання, якого слід уникати, - це Код в анти-шаблоні конструктора , але він не здається таким, про що ви питаєте.


3

Це може бути погано, якщо ви використовуєте SWT, оскільки там вам доведеться прибирати після себе (викликаючи метод dispose ()). Але для інших класів (не SWT) це нормально.

Ось стаття про керування ресурсами операційної системи


Циркулярні посилання не заважають об'єктам збирати сміття на Яві. Будь-який сучасний Java VM визначає, чи є об'єкти GCable на основі того, чи є вони доступними, і не використовує підрахунок посилань.
jbindel

2
Дійсно, він не використовує підрахунку посилань. Але SWT - це особливий випадок, коли нам дійсно потрібно зателефонувати dispose (), хоча спочатку не потрібно викликати будь-який файл retain ().
Олексій

Я мав на увазі посилатися лише на випадок, що не є SWT.
jbindel

Ось стаття про керування ресурсами операційної системи eclipse.org/articles/swt-design-2/swt-design-2.html
Alex

2
У такому випадку відредагуйте свою відповідь, щоб видалити твердження про "неможливо для GC", оскільки воно вводить в оману.
стипендіати доналу

1

Перш за все, ви будете дратувати людей, які вивчали C або C ++ перед Java. Я залишу це як вправу для того, щоб читач вирішив, чи це професіонал, чи проти.

Хоча, безумовно, є ситуації, коли об’єкти розраховані на дуже короткочасну, більшість часу, якщо для створення об'єкта щось досить складне, достатньо складних, щоб мати вагомі причини для збереження посилання, тому не тримати його слід принаймні, будьте попередженням повторно перевірити, чи щось ви пропустили.

Наприклад, у навчальному посібнику ніхто не піклується про те, щоб зберегти посилання на нитку, але в реальному житті, якщо щось займає досить довго, що ви хочете нереститися, зазвичай це займає достатньо часу, щоб ви могли скасувати потік. Або якщо короткоживучі, зазвичай, ви нерестуєте нитку ниток, яку вам захочеться, joinперш ніж продовжувати. Або ви хочете переконатися, що створення вашої нитки насправді вдалося. Або ви хочете переконатися, що нитка чисто закінчується перед виходом. Ви отримуєте картину.


2
Чи хвилюватися з прикрою програмістів з інших мов справді перше питання?
Кнопки840

Це робить проблему читабельності / знайомства / стилю залежно від складу вашої команди, адже це стиль, який багато людей переносять. Навіть люди, які ніколи не програмували на C ++, часто переймають стилі у своїх наставників.
Карл Білефельдт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.