Java中的反射和内部类是什么?

3

嗨,我想使用反射获取内部类的对象,但是我遇到了一些错误。

代码如下:

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)
4个回答

1
使用这个:

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");
    }
}

请查看getDeclaredConstructor(Class<?>... parameterTypes)方法的Javadoc。其中写道:

如果该Class对象表示在非静态上下文中声明的内部类,则形式参数类型包括显式的封闭实例作为第一个参数。

因此,将封闭实例作为第一个参数传递将创建内部类的新实例:
    TestReflection innerInstance = (TestReflection) constructor
            .newInstance(outerInstance);

1

由于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");
        }
    }

}

0
首先,非静态内部类只能使用外部类实例化,例如
Outer outer = new Outer();
Inner inner = outer.new Inner();

其次 - 据我所知,Java反射API不提供实例化非静态内部类的能力。这仅适用于静态内部类。因此,如果您不需要内部类是动态的并且与外部实例相关联 - 只需为内部类添加“static”修饰符,您的代码将正常工作。

它通过向所有非静态内部类构造函数添加一个隐藏参数来提供它,该参数接受封闭类的实例。 - SamYonnou

0

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的实例,即:Class.forName("reflaction.MyReflection").newInstance();,然后从该实例中加载"reflaction.MyReflection$TestReflection"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接