14
March

Анонимные классы в Java

Posted in: Java technologies, J2SE |

English version of this article you can find here.
Практически во всех статьях об inner классах допущен ряд ошибок по поводу анонимных классов:

  • они не имеют имени;
  • они не могут быть объявлены статическими;
  • они могут быть созданы только один раз при декларировании.

Это все неправда!
Допустим у нас есть следующий код:

public class Anonymous {
   public static void main(String[] args) {
    Runnable anonym = new Runnable() {
      public void run() {
      }
    };
  }
}

Имя анонимного класса можно получить так:

anonym.getClass().toString().

Скорее всего вы получите что-то вроде этого: Anonymous$1.
Анонимный класс может быть как статическим, так и нестатическим. Это напрямую зависит от того, статическим или нестатическим является блок, в котором анонимный класс был объявлен. В примере, который указан выше, анонимный класс будет статическим. В этом случае можно создать еще один экземпляр класса таким способом:

Runnable anonym2 = (Runnable) anonym
    .getClass().newInstance().

В версии JDK 1.5 приведение типа (по-русски type cast :)) делать не нужно.
Если же анонимный класс был объявлен внутри нестатического блока, то для создания второго экземпляра анонимного класса нужно передать в его конструктор ссылку на обрамляющий класс. В противном случае получим InstantiationException.
Вот небольшой пример. Для его упрощения, я не использовал алгоритм поиска необходимого конструктора и списка его формальных параметров, а также опустил обработку Exception.

public class Anonymous {
  public void nonStaticMethod() {
    Runnable anonym = new Runnable() {
      public void run() {
      }
    };
    Constructor[] constructors = anonym.getClass()
            .getDeclaredConstructors();
    Object[] params = new Object[1];
    params[0] = this;

    Runnable anonym2 = (Runnable) constructors[0].newInstance(params);
  }

  public static void main(String[] args) {
    Anonymous example = new Anonymous();
    example.nonStaticMethod();
  }
}

Интересующий нас конструктор имеет модификатор видимости protected. Функция getConstructors(), в отличии от getDeclaredConstructors(), вернет список только public конструкторов.
Надеюсь, статья была вам интересна. В любом случае, комментарии приветствуются.

3 Comments »

RSS feed for comments on this post. TrackBack URI



pilgrim
June 22, 2006 #

Отличная статья!
P.S. “Пеши исчо”

ааа
October 18, 2006 #

статья хорошая. короткая. понятная. простая. без лишних загогулин. хорошо что есть люди которые такую инфу вывешивают. вообще классные наблюдения :)

Twister
November 10, 2006 #

Дзенкую барзо!

Отличный сайт :)

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>