Обычная версия
Java форум JavaTalks
форум программистов

Поиск   Пользователи   Группы   Регистрация 
 Профиль   Личные сообщения 

 Вход 

Inner classes && Static inner classes
Список форумов
 ->  Разное


На страницу 1, 2  След. 
Начать новую тему 
Предыдущая тема :: Следующая тема  
Автор Сообщение
initmax : 165
Новичок
Откуда: Moon

СообщениеИюн 21, 2011 9:21 
Ответить с цитатой
Возникли рассуждения по поводу Inner classes и
Static inner classes в чём так сказать существенные различия. Благодаря Inner classes осуществляется агрегирование, что позволяет повысить инкапсуляцию за счёт скрытия реализации, НО почему просто не использовать методы а создавать вложенную сущность?
касательно же Static inner classes исходя из философии Java данные экзепляры создаются в момент компиляции и вызывать методы этих классов можно не создавая экзепляра объекта т.е. NameClass.NameMethod. это и вся разница, или есть какие-то ещё аспекты?
_________________
Пишу дипломы, курсовые, лабары. Консультирую по скайпу до полного прозрения. Обращайтесь в личку.
К началу Посмотреть профиль Отправить личное сообщение
Skipy : 4801
Я тут живу!
Откуда: Москва, Россия

СообщениеИюн 21, 2011 12:42 
Ответить с цитатой
initmax писал(а):
НО почему просто не использовать методы а создавать вложенную сущность?


Сколько вариантов ActionListener-а Вы можете реализовать методами в текущем классе? А кнопок у Вас пять штук, и каждой нужен свой.
_________________
С уважением,
Евгений aka Skipy
www.skipy.ru
P.S. Я НЕ решаю задачи ЗА других!
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
initmax : 165
Новичок
Откуда: Moon

СообщениеИюн 21, 2011 15:20 
Ответить с цитатой
Skipy писал(а):
initmax писал(а):
НО почему просто не использовать методы а создавать вложенную сущность?


Сколько вариантов ActionListener-а Вы можете реализовать методами в текущем классе? А кнопок у Вас пять штук, и каждой нужен свой.


Признаться откровенно, понял Вас весьма смутно и как минимум в двух вариантах Smile Вы бы могли более подробно изложить свои мысли касательно данного вопроса?
_________________
Пишу дипломы, курсовые, лабары. Консультирую по скайпу до полного прозрения. Обращайтесь в личку.
К началу Посмотреть профиль Отправить личное сообщение
Skipy : 4801
Я тут живу!
Откуда: Москва, Россия

СообщениеИюн 21, 2011 17:20 
Ответить с цитатой
У Вас есть класс. В нем нужно создать реализацию ActionListener. Варианты - либо в самом классе реализовать actionPerformed, либо сделать внутренний класс. Вопрос: сколько вариантов реализации ActionListener-а возможно в первом случае и сколько во втором?
_________________
С уважением,
Евгений aka Skipy
www.skipy.ru
P.S. Я НЕ решаю задачи ЗА других!
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
initmax : 165
Новичок
Откуда: Moon

СообщениеИюн 21, 2011 17:23 
Ответить с цитатой
Skipy писал(а):
У Вас есть класс. В нем нужно создать реализацию ActionListener. Варианты - либо в самом классе реализовать actionPerformed, либо сделать внутренний класс. Вопрос: сколько вариантов реализации ActionListener-а возможно в первом случае и сколько во втором?


создать реализацию ActionListener
Если я Вас верно понял требуется создать множество методов обработки нажатия кнопок, в чём разница где их создавать во вложеном классе или просто в классе. Вот в чём у меня недопонимание.
_________________
Пишу дипломы, курсовые, лабары. Консультирую по скайпу до полного прозрения. Обращайтесь в личку.
К началу Посмотреть профиль Отправить личное сообщение
oleg_v_ : 90
Новичок
Откуда: Санкт-Петербург, Россия

СообщениеИюн 21, 2011 17:35 
Ответить с цитатой
Вот для примера два варианта реализации ActionListener для двух кнопок:

без Inner classes:
Код:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


public class TwoButtons implements ActionListener {

    JFrame frame;
    JLabel label;
   
   JButton colorButton;

    public static void main (String[] args) {
       TwoButtons gui = new TwoButtons();
       gui.go();
    }

    public void go() {
       frame = new JFrame();
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

       JButton labelButton = new JButton("Change Label");
       labelButton.addActionListener(this);

       colorButton = new JButton("Change Circle");
       colorButton.addActionListener(this);

       label = new JLabel("I'm a label");       
       MyDrawPanel drawPanel = new MyDrawPanel();
       
       frame.getContentPane().add(BorderLayout.SOUTH, colorButton);
       frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
       frame.getContentPane().add(BorderLayout.EAST, labelButton);
       frame.getContentPane().add(BorderLayout.WEST, label);

       frame.setSize(420,300);
       frame.setVisible(true);
    }
   
   public void actionPerformed(ActionEvent event){
      if (event.getSource() == colorButton){
         frame.repaint();
      }else{
         label.setText("That hurt!");
      }
   }
}

class MyDrawPanel extends JPanel {
   
      public void paintComponent(Graphics g) {
         
         g.fillRect(0,0,this.getWidth(), this.getHeight());

         // make random colors to fill with
         int red = (int) (Math.random() * 255);
         int green = (int) (Math.random() * 255);
         int blue = (int) (Math.random() * 255);

         Color randomColor = new Color(red, green, blue);
         g.setColor(randomColor);
         g.fillOval(70,70,100,100);
      }

}


с Inner classes:

Код:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


public class TwoButtons  {

    JFrame frame;
    JLabel label;

    public static void main (String[] args) {
       TwoButtons gui = new TwoButtons();
       gui.go();
    }

    public void go() {
       frame = new JFrame();
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

       JButton labelButton = new JButton("Change Label");
       labelButton.addActionListener(new LabelButtonListener());

       JButton colorButton = new JButton("Change Circle");
       colorButton.addActionListener(new ColorButtonListener());

       label = new JLabel("I'm a label");       
       MyDrawPanel drawPanel = new MyDrawPanel();
       
       frame.getContentPane().add(BorderLayout.SOUTH, colorButton);
       frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
       frame.getContentPane().add(BorderLayout.EAST, labelButton);
       frame.getContentPane().add(BorderLayout.WEST, label);

       frame.setSize(420,300);
       frame.setVisible(true);
    }
   
     class LabelButtonListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            label.setText("Ouch!");
        }
     } // inner class

     class ColorButtonListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            frame.repaint();
        }
     }  // inner class
   
}

class MyDrawPanel extends JPanel {
   
      public void paintComponent(Graphics g) {
         
         g.fillRect(0,0,this.getWidth(), this.getHeight());

         // make random colors to fill with
         int red = (int) (Math.random() * 255);
         int green = (int) (Math.random() * 255);
         int blue = (int) (Math.random() * 255);

         Color randomColor = new Color(red, green, blue);
         g.setColor(randomColor);
         g.fillOval(70,70,100,100);
      }

}


Можно делать как в первом варианте и иногда может это оправдано, а если кнопок будет больше чем две? А если Вам нужно будет изменить обработку события от какого-нибудь из кнопок.
К началу Посмотреть профиль Отправить личное сообщение
Skipy : 4801
Я тут живу!
Откуда: Москва, Россия

СообщениеИюн 21, 2011 18:11 
Ответить с цитатой
initmax писал(а):
Если я Вас верно понял требуется создать множество методов обработки нажатия кнопок, в чём разница где их создавать во вложеном классе или просто в классе. Вот в чём у меня недопонимание.


Повторяю вопрос - сколько таких методов Вы можете сделать в одном классе? Напоминаю - у них у всех одинаковая сигнатура должна быть! Сколько методов с одинаковой сигнатурой можно сделать в классе?
_________________
С уважением,
Евгений aka Skipy
www.skipy.ru
P.S. Я НЕ решаю задачи ЗА других!
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
initmax : 165
Новичок
Откуда: Moon

СообщениеИюн 21, 2011 19:15 
Ответить с цитатой
Skipy писал(а):
initmax писал(а):
Если я Вас верно понял требуется создать множество методов обработки нажатия кнопок, в чём разница где их создавать во вложеном классе или просто в классе. Вот в чём у меня недопонимание.


Повторяю вопрос - сколько таких методов Вы можете сделать в одном классе? Напоминаю - у них у всех одинаковая сигнатура должна быть! Сколько методов с одинаковой сигнатурой можно сделать в классе?


Одноимённых методов с одним и тем же кол. параметров 1
_________________
Пишу дипломы, курсовые, лабары. Консультирую по скайпу до полного прозрения. Обращайтесь в личку.
К началу Посмотреть профиль Отправить личное сообщение
sgdread : 2184
JT Библиотекарь
Откуда: USA

СообщениеИюн 21, 2011 23:17 
Ответить с цитатой
У Inner-классов есть одна большая проблема - они порождают утечки памяти. Случается это из-за того, что порождающий класс неявно передает ссылку на себя анонимному классу (просто декомпилируйте class-файлы и все увидите), а это значит, что пока мы держим ссылку на экземпляр внутреннего класса, внешний класс не может быть собран. Пруф.
Вот-тут типичный пример из Swing-а с утечкой памяти через ActionListener.
Static Inner-классы такой проблемы решены. По сути вторые ничем не отличаются от обычных классов.
_________________
К началу Посмотреть профиль Отправить личное сообщение
bomba_flanker : 1582
Завсегдатай
Откуда: Мск/Ульяновск

СообщениеИюн 22, 2011 9:08 
Ответить с цитатой
Хорстманн писал(а):
Может случиться так, что вам нужно будет использовать внутренний класс просто для того, чтобы скрыть его внутри другого класса, а ссылка на объект внешнего класса окажется ненужной. Подавить генерацию этой ссылки можно, объявив внутренний класс статическим (static).
...
Разумеется, только внутренние классы можно объявлять статическими. Статический внутренний класс ничем не отличается от любого другого внутреннего класса, за исключением того, что его объект не содержит ссылку на создавший его объект внешнего класса.
Код:
public class Outer {

    private String value;
   
    public Outer() {
        value = "1";
    }
   
    private class Inner {
       
        void doSomething() {
            value = "2"; //нет проблем
        }
    }
}
Код:
public class Outer {

    private String value;
   
    public Outer() {
        value = "1";
    }
   
    private static class Inner {
       
        void doSomething() {
            value = "2"; //ошибка
        }
    }
}
sgdread писал(а):
Static Inner-классы такой проблемы решены. По сути вторые ничем не отличаются от обычных классов.
Спасибо sgdread и <ТС>initmax</ТС>! Такие темы и ответы заставляют копнуть глубже, чтобы разобраться в тонкостях.
_________________
Google Вам в помощь
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
Skipy : 4801
Я тут живу!
Откуда: Москва, Россия

СообщениеИюн 22, 2011 10:03 
Ответить с цитатой
sgdread писал(а):
Вот-тут[/url] типичный пример из Swing-а с утечкой памяти через ActionListener.


Давайте все-таки отделять мух от котлет. Это не утечка памяти, это небрежность разработчика, не удосужившегося убрать слушателей. Да, такая конструкция весьма популярна, и очень многие не задумываются об утечках. Но считать это проблемой именно иннер-классов... Я вон видел утечку, сотворенную на Map-е. Из него просто не убирались обработанные объекты. Полчаса работы, гиг памяти в минус и OOM как следствие. Ну это же не проблема Map-а?
_________________
С уважением,
Евгений aka Skipy
www.skipy.ru
P.S. Я НЕ решаю задачи ЗА других!
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
initmax : 165
Новичок
Откуда: Moon

СообщениеИюн 22, 2011 12:04 
Ответить с цитатой
Благодарю за ответы, статические классы создаются в единственном экзепляре и избавляют от "утечек памяти" хотелось бы увидеть пример где невозможно обойтись без Static inner классов.
_________________
Пишу дипломы, курсовые, лабары. Консультирую по скайпу до полного прозрения. Обращайтесь в личку.
К началу Посмотреть профиль Отправить личное сообщение
Skipy : 4801
Я тут живу!
Откуда: Москва, Россия

СообщениеИюн 22, 2011 14:05 
Ответить с цитатой
initmax писал(а):
Благодарю за ответы, статические классы создаются в единственном экзепляре и избавляют от "утечек памяти"


Вот именно таких выводов и хотелось избежать. Не вышло.

Статические классы создаются в любом количестве экземпляров. Их отличие от нестатических только в том, что они не имеют ссылки на внешний класс. И, соответстветственно, не могут обращаться к переменным "их" экземпляра внешнего класса, для них вообще не существует понятия "их" экземпляра.

Ни от каких утечек статические классы не избавляют и не могут избавить. Утечка - это не следствие (не)статичности класса, это следствие ошибки разработчика вследствие незнания им каких-либо фактов (типа неявного наличия ссылок на "свой" экземпляр внешнего класса). Если бы в приведенном примере сохранялась ссылка на создаваемый внутренний класс, так, что потом бы этот слушатель удалялся - утечки бы не было.
_________________
С уважением,
Евгений aka Skipy
www.skipy.ru
P.S. Я НЕ решаю задачи ЗА других!
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
sgdread : 2184
JT Библиотекарь
Откуда: USA

СообщениеИюн 22, 2011 20:21 
Ответить с цитатой
Skipy писал(а):
Давайте все-таки отделять мух от котлет. Это не утечка памяти, это небрежность разработчика, не удосужившегося убрать слушателей. Да, такая конструкция весьма популярна, и очень многие не задумываются об утечках. Но считать это проблемой именно иннер-классов...

Ну вы бы почитали сначала, что я написал. Даже если вы уберете слушатели через removeListener, утечка останется. Причина не в добавлении/удалении, а в том, что анонимный inner-класс неявно содержит ссылку на объект-родитель (возьмите декомпилируйте код с inner-классом и увидите своими глазами - в анонимный класс передается this объекта-родителя). В результате, если у вас есть кнопочка, которая создает новое модальное окно, слушатель на которой - анонимный класс, вы получити феерическую утечку памяти - все модальные окна, созданные таким ActionListener-ом будут храниться в памяти и не будут собраны, пока не будет собран компонент с кнопочкой. Проблема ИМЕННО в анонимных inner-классах.
Skipy писал(а):
Я вон видел утечку, сотворенную на Map-е. Из него просто не убирались обработанные объекты. Полчаса работы, гиг памяти в минус и OOM как следствие. Ну это же не проблема Map-а?

Утечки на Map-ах - это слишком банально. Достаточно сделать mutable-ключи, чтобы у них менялся hashCode.
_________________
К началу Посмотреть профиль Отправить личное сообщение
Vermut : 1062
Завсегдатай
Откуда: Ростов-на-Дону

СообщениеИюн 22, 2011 21:15 
Ответить с цитатой
sgdread писал(а):
В результате, если у вас есть кнопочка, которая создает новое модальное окно, слушатель на которой - анонимный класс, вы получити феерическую утечку памяти - все модальные окна, созданные таким ActionListener-ом будут храниться в памяти и не будут собраны, пока не будет собран компонент с кнопочкой. Проблема ИМЕННО в анонимных inner-классах.

Что помешает собирать сборщику мусора создаваемые в листенере окна, ведь он же запоминает ссылку не на них, а на родительский объект?
_________________
Познакомлюсь с привлекательной Ростовчанкой для совместного изучения Java
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
 
Начать новую тему  Ответить на тему
Страница 1 из 2
На страницу 1, 2  След.
Список форумов
 -> Разное


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


Java and all Java-related trademarks and logos are trademarks or registered trademarks of Oracle Corporation in the United States and other countries.
Это сайт не относится к фирме Oracle Corporation и не поддерживается ею.

© 2006-2010 www.javatalks.ru: форум java программистов
Используется скрипт phpBB © 2001, 2010 phpBB Group

Хостинг от bizname.ru