下面是一个例子:
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 { }
}虽然知道非静态内部类只能在非静态方法中实例化,但是今天才知道实例化还不能通过反射来实现。这个报错到底是为什么呢?
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)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();正确的原因.
/**
* 实例化内部类
*/
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()方法
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();
就行了
http://blog.csdn.net/YidingHe/archive/2009/02/27/3943524.aspx
一个牛人的说,学习,学习。
经过尝试,默认构造参数十分隐蔽的哦
内部类不加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