java的反射功能基本上在任何的代码包中都可以看到,通过反射可以实例化出一个类的对象,那么对于类中的内部类的通过这种方式实例化过程,还是需要注意的,因为不同类型的内部类,实例化的方式是不一样的
本文主要以普通内部类和静态内部类来举例,先上代码:
/**
* 类名称 Home
* 说明 TODO
*
* @Author xingqing
* 日期 2021-02-21 16:14
*/
public class Home {
void have () throws Exception {
Class<Desk> deskClass = Desk.class;
// 普通内部类进行实例化,需要指定父类以及父类对象
Desk desk = deskClass.getDeclaredConstructor(Home.class).newInstance(this);
desk.legCount();
Class<Chair> chairClass = Chair.class;
// 静态内部类不需要指定
Chair chair = chairClass.getDeclaredConstructor().newInstance();
chair.chairCount();
}
public static void main(String[] args) throws Exception {
Home home = new Home();
home.have();
}
// 普通内部类
class Desk {
Desk () {
}
void legCount() {
System.out.println("4");
}
}
// 静态内部类
static class Chair {
Chair() {
}
void chairCount() {
System.out.println("4");
}
}
}
解释:
一个普通的Desk内部类和一个静态内部类,在通过反射来实例化的 过程中,是有区别的
通过上面两个截图,其实已经很明确,在对普通的内部类获取构造器时间,一定要加上父类的类类对象以及实力对象;而在对静态内部类时间,无需传递父类参数,这个的原因是JVM虚拟机在编译时不一样的处理而导致的,那么我们反编译class类,上述代码一共会产生三个class类文件,如下图
home的反编译代码我们就不看了,主要看Chair和Desk的反编译代码
import java.io.PrintStream;
class Home$Chair
{
void chairCount()
{
System.out.println("4");
}
}
import java.io.PrintStream;
class Home$Desk
{
Home$Desk(Home this$0) {}
void legCount()
{
System.out.println("4");
}
}
那么显而易见了,反编译Desk的编译后的代码后,发现本身无参数的构造函数,有了参数,如果这时间,还是使用无参数的构造器进行实例化时,一定是会报错的!所以大家一定要注意和留心!