March
2006
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 конструкторов.
Надеюсь, статья была вам интересна. В любом случае, комментарии приветствуются.
Еще про внутренние классы в Java можно прочитать здесь - Внтуренние классы в Java.
Updated (26.08.2009):
“За все, что Вы когда-либо писали, Вам придется отвечать всю остав?уюся жизнь…” (c) Костя Чапюк, то есть я
Время идет, многие статьи на блоге уже постарели и поседели… Тем не менее до сих пор находятся люди, которые не смотрят на дату публикации статей и почему-то хотят задеть меня или унизить мои “многолетназад?ние” порывы вести свой блог и делиться с миром моими наблюдениями.
Например, комментарий от bsv:
пожалуйста получи имя этого анонимного класса .)
new Thread(new Runnable() {
public void run() {
…
}
}).start();
твой пример по этому поводу, извени, слегка притянут за у?и .)
Хотел сначала проигнорировать, но может кому-то интересно будет. Позволю себе немного упростить задание, а то с тремя точками плохо компилится…
public class LookHereItIs {
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
while (true)
try { Thread.sleep(1000); }
catch (InterruptedException e) { }
}
}).start();
ThreadGroup group = Thread.currentThread().getThreadGroup();
Thread[] threads = new Thread[group.activeCount()];
group.enumerate(threads);
Field field;
try { field = Thread.class.getDeclaredField("target"); }
catch (NoSuchFieldException e) { throw new RuntimeException(e); }
field.setAccessible(true);
Runnable runnable;
try { runnable = (Runnable) field.get(threads[1]); }
catch (IllegalAccessException e) { throw new RuntimeException(e); }
System.out.println(runnable.getClass().toString());
}
}
P.S. ?ндекс “1″ за у?и не притянут… Можно было выкинуть из массива currentThread; остав?ийся Thread - на? клиент.
8 Comments »
RSS feed for comments on this post. TrackBack URI
Отличная статья!
P.S. “Пе?и исчо”
статья хоро?ая. короткая. понятная. простая. без ли?них загогулин. хоро?о что есть люди которые такую инфу выве?ивают. вообще классные наблюдения ![]()
Дзенкую барзо!
Отличный сайт ![]()
пожалуйста получи имя этого анонимного класса .)
new Thread(new Runnable() {
public void run() {
…
}
}).start();
твой пример по этому поводу, извени, слегка притянут за у?и .)
2 bsv: дополнил статью
[…] другим углом обзора. Поясню луч?е на примере. В статье Анонимные классы в Java (anonymous inner classes) автор опровергает такие утверждения об анонимных […]
Малацца! Так держать!
Очень хоро?ая статья, при внимательном чтении помогает понять механизм обработки анонимных классов, на мой взгляд это гораздо более глубокий уровень понимания.
Спасибо боль?ое за такую информацию! ![]()