Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java ME (J2ME) > Один экземпляр класса на всю программу?


Автор: Kalisnik 29.5.2012, 19:57
Глупый наверно вопрос, но что-то волнует он меня )) 

Допустим у меня есть 4 класса: A, B, C, D. 
Мне нужно что бы в классах A, B и C использовался один и тот же экземпляр класса D.
Что я делаю. Создаю один экземпляр в классе A и раздаю его через get'ры остальным. Но при такой модели A уж больно сильно разрастается этими get'рами. Это невольно подводит к мысли что логика не верна. Как это делается правильно? В других языках вроде можно целый класс сделать статическим, только в java такой вариант не проходит.


P.S. Или до лампы сколько этих экземпляров D в программе, просто нужные поля и методы в нем помечаешь как static и все? Думал просто не загружать систему лишними и в общем-то ненужными объектами. И как интересно два экземпляра одного класса используют одно и тоже поле static? Физически это поле в одной ячейки памяти находится? 

Автор: oxigen 30.5.2012, 11:37
Ключевое слово для поиска - singletone (синглтон)

простейший пример:

Код

public class Single {
private static Single instance;  // единственный экземпляр

private Single() { //конструктор private, чтоб нельзя было снаружи создавать новые экземпляры через new
}

 public static Single getInstance() {
        if (instance == null) {
            instance = new Single();
        }
        return instance;
    }

}

//Использование:

Single s = Single.getInstance(); //всегда возвращает ссылку на единственный объект класса Single 


Автор: oxigen 30.5.2012, 11:54
И как интересно два экземпляра одного класса используют одно и тоже поле static? Физически это поле в одной ячейки памяти находится? 
Так и есть. 
В java есть такой интересный класс, который так и называется Class
Он создается в единственном экземпляре при первом обращении к классу (при его загрузке). В нем и находятся все статические поля и методы.
И каждый объект класса имеет ссылку на него. o.getClass();

Автор: Kalisnik 31.5.2012, 16:48
oxigen, спасибо. Только на Ваших ответах в основном и учусь. smile

Добавлено через 9 минут и 50 секунд
Цитата(oxigen @  30.5.2012,  11:37 Найти цитируемый пост)
простейший пример:


Ха! Действительно, все логично и просто. А я даже и не подумал так сделать. )))

Автор: Kalisnik 3.6.2012, 21:28
Цитата(oxigen @  30.5.2012,  11:37 Найти цитируемый пост)
простейший пример:


Написано, что это решение не работает в многопоточной среде. Почему?

Автор: oxigen 5.6.2012, 15:58
Код

 public static Single getInstance() {
        if (instance == null) {
            instance = new Single();
        }
        return instance;
    }

Не совсем правильно, что оно "не работает в многопоточной среде"
Просто возможна такая ситуация: 

Два потока обращаются к этому методу одновременно(почти).
Первый видит, что instance==null и начинает выполнять  new Single();
В это время сюда же заходит второй поток - instance по прежнему null (пока первый поток не закончил выполнение конструктора, присваивание не произошло)
И вот второй поток тоже начинает выполнять new Single();
В итоге создалось два экземпляра Single. Один для первого потока, один для второго.

Но в MIDP приложениях Вы вряд ли столкнетесь с подобным случаем.

Автор: Pawl 5.6.2012, 16:54
Цитата(oxigen @  5.6.2012,  15:58 Найти цитируемый пост)
В итоге создалось два экземпляра Single. Один для первого потока, один для второго.

Хмм... А выход тут, в принципе, какой? Объявить метод getInstance() синхронизированным?

Автор: oxigen 5.6.2012, 17:14
Цитата(Pawl @ 5.6.2012,  16:54)
Цитата(oxigen @  5.6.2012,  15:58 Найти цитируемый пост)
В итоге создалось два экземпляра Single. Один для первого потока, один для второго.

Хмм... А выход тут, в принципе, какой? Объявить метод getInstance() синхронизированным?

Да по этому поводу куча рецептов есть.  Со своими достоинствами и недостатками.
Можно synchronized сделать, но это по производительности плохо.
можно от ленивой инициализации избавиться
Код

private static final Single instance = new Single();

И еще куча всего.

Паттерн распространенный и написано по его поводу очень много.

Автор: Pawl 5.6.2012, 22:07
Цитата(oxigen @  5.6.2012,  17:14 Найти цитируемый пост)
можно от ленивой инициализации избавиться

Да, это хороший способ!
Немного не в тему. oxigen, я смотрю, эта ветка, в основном, жива Вашими ответами. Поскольку те, кому Вы тут помогаете, пока не в состоянии оценить Вашу помощь, это сделаю я. Итак, Вам +.

Автор: Kalisnik 6.6.2012, 10:07
oxigen, спасибо. Уяснил smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)