下面是一个例子:
package tests;/**
 * 实例化内部类
 */
public class TestInnerClass {    public static void main(String[] args) throws Exception {
        new TestInnerClass().createInner3Object();
    }    void createInner3Object() throws Exception {
        Inner ii = new Inner();
        Inner i = (Inner) Class.forName("tests.TestInnerClass$Inner").newInstance();    // 报错
    }    class Inner {    }
}虽然知道非静态内部类只能在非静态方法中实例化,但是今天才知道实例化还不能通过反射来实现。这个报错到底是为什么呢?

解决方案 »

  1.   

    标题有误,应该是“为什么非静态内部类不能通过反射实例化?”CSDN 不能修改帖子这点实在不爽。
      

  2.   

    问:
    1)Inner i = (Inner) Class.forName("tests.TestInnerClass$Inner").newInstance();    // 报错
    2)今天才知道实例化还不能通过反射来实现。这个报错到底是为什么呢? 答:
    肯定报错啊.原因是:
    1)newInstance()中讲得很清楚,它等价于调用该类的无参的构造器,即:默认构造器.
    2)而在你的内部类:
    class Inner {
        }
    中,实际上不存在无参的构造器的.为什么?你从源程序上看,在
    class Inner中没有定义任何构造器,因而编译器会自动帮我们生成一个,这个就是默认构造器.但要注意:对于非static型的内部类,这个自动生成的构造器其实是这样的:
     TestInnerClass$Inner(TestInnerClass outer)
    {}它是带有一个参数的,是外部类对象的引用.因此:由于内部其实是不存在无参的构造器的,而newInstance()就是通过调用无参的构造器来初始化对象的,因此:当然会报出InstantiationException了(初始化异常了)3)要说明的是:我们自己在程序中生成内部类对象时,是用:
    outer.new Inner();方式来生成对象的.从源程序看:确实是调用的Inner类的无参构造器,但实际上,编译时,是等价调用的 new TestInnerClass$Inner(outer);来生成对象的.这就是通过CLass.forName(...).newInstance()报错outer.new Inner();正确的原因.
      

  3.   

    可以通过import java.lang.reflect.Constructor;   
      
    /**
     * 实例化内部类
     */
    public class TestInnerClass { public static void main(String[] args) {      
         // TODO Auto-generated method stub      
     TestInnerClass test = new TestInnerClass();      
         for (Class c : test.getClass().getClasses()) {      
             try {      
                 System.out.println(c.getName());      
                 c.newInstance();                 
             } catch (Exception e) {      
                 try {   
                     Constructor con = c.getConstructor(new Class[] {TestInnerClass.class});   
                     con.newInstance(new Object[] {test});   
                 } catch (Exception e1) {   
                     e1.printStackTrace();   
                 }      
             } 
         } 
      }      
      
     public class Inner{    
      
         public void say() {      
             System.out.println("say hello");      
         }  
         public Inner ()
         {
          System.out.println("实例化内部类");
         }
     }     }
    实例化内部类,在这也输出了内部类的名字是:bcdc.test.TestInnerClass$Inner
    但是就是不能通过bcdc.test.TestInnerClass$Inner来是实例化,不知道什么原因还有,不知道如何来调用Inner中的say()方法
      

  4.   

    答:
    1)你的代码实际上是通过Constructor对象的newInstance(Object....args)来强制调用TestInnerClass$Inner(TestInnerClass outer) 这个构造器来创建对象的.而不是楼主的通过Class.forName(....).newInstance();来创建对象的.实际上:你的代码中:
    try {      
                 System.out.println(c.getName());      
                 c.newInstance();   //<===这个是不可能创建对象的.原因在3楼.正是这个才是楼主所问的问题.              
             } catch (Exception e) {   而你所讲的对象创建成实际上是由你的:
    Constructor con = c.getConstructor(new Class[] {TestInnerClass.class});   
    con.newInstance(new Object[] {test});  //<==强制调用TestInnerClass$Inner(TestInnerClass outer) 这个构造器来创建对象的 2)不知道如何来调用Inner中的say()方法?
    很简单:代码如下:
     Constructor con = c.getConstructor(new Class[] {TestInnerClass.class});   
     Inner in=(Inner)con.newInstance(new Object[] {test});   
     in.say();

    就行了
      

  5.   

    3 楼说的基本上是对的,因为 Inner 不是静态的,所以没有缺省构造函数。而且因为它不是公共的,所以构造函数必须用 getDeclaredConstructor() 来获得。今天学到不少啊。暂不结贴,明天来加分!参考:
    http://blog.csdn.net/YidingHe/archive/2009/02/27/3943524.aspx
      

  6.   

    首先 学习了,很久不来了,今天第二贴就见到 云上飞翔 
    一个牛人的说,学习,学习。
    经过尝试,默认构造参数十分隐蔽的哦
    内部类不加public 的用getDeclaredClasses
    package test;import java.lang.reflect.Constructor;
    public class TestInnerClass { public static void main(String[] args) throws Exception {
    new TestInnerClass().createInner3Object();
    } void createInner3Object() throws Exception {
    Class clazz = Class.forName("test.TestInnerClass$Inner");
    Class[] dclasses = this.getClass().getDeclaredClasses();
    for (Class c : dclasses) {
    Constructor constructor = null;
    try {
    constructor = (Constructor) c.getConstructor(this.getClass());
    Inner i = (Inner) constructor.newInstance(this);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }   class Inner {
    public Inner(TestInnerClass c) {
    System.out.println("Inner 1");
    } public Inner() {//去掉此函数无法实例化
    System.out.println("Inner 2");
    }
    }
    }
    输出
    Inner 2