Java: Как загрузить класс (и его внутренние классы), который уже находится на пути к классам? - PullRequest
7 голосов
/ 19 мая 2010

Как я могу загрузить класс, который уже находится в пути к классу, создать его экземпляр, а также создать экземпляр любых внутренних классов, определенных в нем?

EG:

public class TestClass {


    public class InnerClass { }

}

Ответы [ 3 ]

15 голосов
/ 19 мая 2010

Внутренние классы не могут существовать вне родительского класса. Вы должны сначала создать родительский класс. Без отражения это будет выглядеть так:

InnerClass innerClass = new TestClass().new InnerClass();

В отражении вам нужно передать родительский класс во время создания внутреннего класса.

Object testClass = Class.forName("com.example.TestClass").newInstance();
for (Class<?> cls : testClass.getClass().getDeclaredClasses()) {
    // You would like to exclude static nested classes 
    // since they require another approach.
    if (!Modifier.isStatic(cls.getModifiers())) {
        Object innerClass = cls
            .getDeclaredConstructor(new Class[] { testClass.getClass() })
            .newInstance(new Object[] { testClass });
    }
}
7 голосов
/ 20 мая 2010

В качестве дополнительного примечания, учитывая, что на ваш основной вопрос был дан ответ - часто люди объявляют внутренние классы, как в вашем примере выше, не задумываясь о том, могут ли они вместо этого быть статическими внутренними классами. 1003 *

По моему опыту, подавляющее большинство (неанонимных) внутренних классов могут быть статическими, поскольку им не требуется доступ к членам экземпляра родительского класса. Объявление внутреннего класса как статического в этом случае является более эффективным (поскольку среда выполнения не должна определять новый класс для каждого родительского экземпляра), менее запутанным (начиная с new TestClass().new InnerClass().getClass() != new TestClass().new InnerClass().getClass()) и более простым для создания экземпляров, если у вас нет подходящий экземпляр TestClass handy.

Так что, если это относится к вам, вы можете (и, возможно, должны) объявить свой внутренний класс таким образом:

public class TestClass {

    public static class InnerClass { }

}

и тогда вы можете просто создать его экземпляр как new TestClass.InnerClass().

(Если вам нужно получить доступ к полям члена из InnerClass, просто проигнорируйте все это, конечно!)

2 голосов
/ 19 мая 2010
Class.forName("your classname").newInstance().

Внутренние классы будут создаваться только в том случае, если их создает конструктор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...