Java, отражение, внутренний класс,

Привет, я хочу получить объект внутреннего класса, используя отражение, но я получаю в нем некоторую ошибку.

код: -

package reflaction;
public class MyReflection {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException  {
    Class obj = Class.forName("reflaction.MyReflection$TestReflection");
    TestReflection a = (TestReflection) obj.newInstance();
    a.demo();
}

class TestReflection {

    public void demo(){
        System.out.println("reflection occurs");
    }
    }
}

а ошибка :--

Exception in thread "main" java.lang.InstantiationException: reflaction.MyReflection$TestReflection
    at java.lang.Class.newInstance0(Class.java:357)
    at java.lang.Class.newInstance(Class.java:325)
    at reflaction.MyReflection.main(MyReflection.java:10)

person user2142786    schedule 30.09.2013    source источник


Ответы (4)


Использовать это:

public class MyReflection {

public static void main(String[] args) throws ClassNotFoundException,
        InstantiationException, IllegalAccessException,
        NoSuchMethodException, SecurityException, IllegalArgumentException,
        InvocationTargetException {
    Class outer = Class.forName("reflaction.MyReflection");
    Object outerInstance = outer.newInstance();

    Class<?> inner = Class
            .forName("reflaction.MyReflection$TestReflection");
    Constructor<?> constructor = inner.getDeclaredConstructor(outer);

    TestReflection innerInstance = (TestReflection) constructor
            .newInstance(outerInstance);

    innerInstance.demo();
}

class TestReflection {

    public void demo() {
        System.out.println("reflection occurs");
    }
}

Взгляните на ссылку Javadoc из getDeclaredConstructor(Class<?>... parameterTypes). В нем говорится:

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

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

    TestReflection innerInstance = (TestReflection) constructor
            .newInstance(outerInstance);
person Kai Sternad    schedule 30.09.2013

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

Использовать это:

public class MyReflection {

    public static void main(String[] args) throws Exception {
        Class<?> testReflectionClass = Class
                .forName("reflection.MyReflection$TestReflection");
        MyReflection myReflection = new MyReflection();
        Object newInstance = testReflectionClass.getDeclaredConstructor(
                MyReflection.class).newInstance(myReflection);
        TestReflection testReflection = (TestReflection) newInstance;
        testReflection.demo();
    }

    class TestReflection {

        public void demo() {
            System.out.println("reflection occurs");
        }
    }

}
person René Link    schedule 30.09.2013

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

Outer outer = new Outer();
Inner inner = outer.new Inner();

Во-вторых, насколько мне известно, API отражения Java не дает возможности создавать экземпляры нестатических внутренних классов. Это возможно только для статических. Поэтому, если вам не нужно, чтобы внутренний класс был динамическим и на него ссылался внешний экземпляр, просто добавьте модификатор 'static' для внутреннего класса, и ваш код заработает.

person Community    schedule 30.09.2013
comment
Он обеспечивает это, добавляя скрытый аргумент ко всем нестатическим конструкторам внутреннего класса, который принимает экземпляр окружающего класса. - person SamYonnou; 30.09.2013
comment
Спасибо большое, действительно не знал. - person ; 30.09.2013

установить TestReflection класс static, например:

package reflaction;

public class MyReflection {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException  {

    Class<?> obj = Class.forName("reflaction.MyReflection$TestReflection");
    TestReflection a = (TestReflection) obj.newInstance();
    a.demo();
}

static class TestReflection {

    public void demo(){
        System.out.println("reflection occurs");
    }
}
}

Другой способ — создать экземпляр MyReflection aka: Class.forName("reflaction.MyReflection").newInstance();, а затем загрузить из этого экземпляра "reflaction.MyReflection$TestReflection".

person Maxim Shoustin    schedule 30.09.2013