Необоснованные анонимные классы в Java - PullRequest
4 голосов
/ 25 июля 2009

Прошло около 6 лет с тех пор, как я написал Java, поэтому прошу прощения за ржавчину.

Я работаю с библиотечным методом, который требует, чтобы я передавал ему Class объекты. Так как мне придется вызывать этот метод динамическое число раз, каждый раз с немного отличающимся аргументом Class, я хотел передать его анонимному классу.

Однако всю документацию / учебные пособия я 'до сих пор удалось найти только разговоры об создании экземпляров анонимных классов, например, :

new className(optional argument list){classBody}

new interfaceName(){classBody}

Могу ли я определить анонимный класс без его создания? Или, может быть, более ясно, я могу создать объект Class для анонимного класса?

Ответы [ 6 ]

2 голосов
/ 25 июля 2009

К сожалению, вы никак не можете избежать этой инстанции. Вы можете сделать его неоперативным, однако:

foo((new Object() { ... }).getClass());

Конечно, это может быть не вариант, если вам нужно наследовать некоторый класс, который выполняет некоторые действия в конструкторе.

РЕДАКТИРОВАТЬ

В вашем вопросе также говорится, что вы хотите вызывать foo "каждый раз с немного другим аргументом класса". Вышеперечисленное не сделает этого, потому что все еще будет один анонимный внутренний класс определение , даже если вы поместите выражение new в цикл. Так что на самом деле он ничего не купит по сравнению с определением именованного класса. В частности, если вы пытаетесь сделать это для захвата значений некоторых локальных переменных, новый экземпляр вашего анонимного класса, который foo создаст с использованием объекта Class, переданного ему , не будет иметь их захватили.

1 голос
/ 26 июля 2009

короткий ответ

вы не можете (используя только классы JDK)

длинный ответ

попробуйте:

public interface Constant {

    int value();
}

public static Class<? extends Constant> classBuilder(final int value) {
    return new Constant() {

        @Override
        public int value() {
            return value;
        }

        @Override
        public String toString() {
            return String.valueOf(value);
        }
    }.getClass();
}

давайте создадим двановые классы "параметрические" классы:

Class<? extends Constant> oneClass = createConstantClass(1);
Class<? extends Constant> twoClass = createConstantClass(2);

однако вы не можете создать эти классы:

Constant one = oneClass.newInstance(); // <--- throws InstantiationException
Constant two = twoClass.newInstance(); // <--- ditto

это не удастся во время выполнения, так как существует только один экземпляр для каждого анонимного класса.

Однако вы можете создавать динамические классы во время выполнения, используя библиотеки манипулирования байт-кодом, такие как ASM . Другой подход заключается в использовании динамических прокси , но этот подход является недостатком, заключающимся в том, что вы можете использовать только методы интерфейса с прокси (поэтому вам необходим интерфейс Java).

0 голосов
/ 11 апреля 2013

Вы можете получить доступ к объекту класса анонимного класса, вызвав .getClass() сразу после создания. Но что хорошего это принесет?

Я думаю, что ключ в этой части того, что вы сказали:

Я работаю с библиотечным методом, который требует, чтобы я передал его Classобъекты.

Почему хочет, чтобы вы передали ему объекты класса? Что эта библиотека делает с объектами Class, которые вы ей передаете? Создавать объекты? Но если да, то какой конструктор он использует и как он решает, какие аргументы передать? Я не знаю, какую библиотеку вы используете или что она делает, но я предполагаю, что она всегда создает объекты, используя конструктор без аргументов. Однако это не сработает в любом случае для анонимных классов, так как у них нет открытого конструктора (и в любом случае для создания экземпляра любого нестатического внутреннего класса необходимо предоставить ссылку на внешний экземпляр, поэтому конструктор без аргументов отсутствует). ).

0 голосов
/ 26 июля 2009

Вы можете принять имя анонимного класса и вызвать Class.forName("mypackage.MyBaseClass$1"), чтобы получить дескриптор анонимного класса. Это даст вам первый анонимный класс, определенный в вашем MyBaseClass, так что это довольно хрупкий способ ссылки на класс.

Я подозреваю, что все, что вы пытаетесь сделать, может быть сделано лучше. Чего вы действительно пытаетесь достичь? Возможно, мы можем предложить способ, который не требует, чтобы вы проходили Class таким путем.

0 голосов
/ 26 июля 2009

Вы не можете получить доступ к объекту Class анонимного класса без его указания. Однако, если вам нужен только доступ к классу, вы можете определить локальные классы в своем методе и ссылаться на них, используя синтаксис литерала ClassName.class.

0 голосов
/ 25 июля 2009

Вы можете ссылаться только на анонимный класс ОДИН РАЗ. Если вы не создадите его экземпляр там, вы не сможете создать его экземпляр, поскольку у вас нет имени для него.

Следовательно, я считаю, что анонимные классы могут использоваться только в сочетании с «новым BaseClass ()».

В вашей ситуации вы передадите объект BaseClass своему методу, выполняющему работу, и создадите экземпляр анонимного объекта в исходном коде, когда вам понадобится передать объект.

...