读书人

反照总结

发布时间: 2012-11-09 10:18:47 作者: rapoo

反射总结

反射就是加载类,并解剖出类的各个组成部分。通俗的说反射就是通过一个文件来解析类。

一、要明白怎样加载类的方法,有三种:

1、Class.forName(""),如:Class.forName("com.mysql.jdbc.Driver")

2、对象.getClass()?如:?Student?st=new?Student();?st.getClass()

3、类名.class?如:?Student.Class;

Class对象提供了如下常用方法:

二、获取加载类中所有的构造器

Public??Constructor??getConstructor(Class<?>...?parameterTypes)?

Public??Method??getMethod(String?name,?Class<?>...?parameterTypes)?

Public??Field??getField(String?name)??

//以上三种可以解析?public类的构造器

//下面的三种方法是解析private类的构造器

public?Constructor?getDeclaredConstructor(Class...?parameterTypes)

public?Method?getDeclaredMethod(String?name,Class...?parameterTypes)

public?Field?getDeclaredField(String?name)

这些方法分别用于从类中解剖出构造函数、方法和成员变量(属性)。解剖出的成员分别使用Constructor、?Method?、?Field?对象表示。常用的是getConstructor()

三、创建类的实例

Constructor类提供了如下方法,用于创建类的对象

public?Object?newInstance(Object...?initargs),initargs用于指定构造函数接收的参数调用对象的方法

四、调用对象的方法

首先以Student类举例如下

(1)、三种加载类的方法

public?class?StudentTest?{

@Test

public?void?test()?throws?ClassNotFoundException?{

//?1、Class.forName("")加载类

Class?cls?=?Class.forName("cn.csdn.reflect.Student");

System.out.println(cls);

//?2、对象.getClass()加载类

Student?stu?=?new?Student();

Class?cls1?=?stu.getClass();

System.out.println(cls1);

//?3、类名.class?加载类

Class?cls2?=?Student.class;

System.out.println(Student.class);

}

(2)、举例反射类无参、有参、私有的构造函数,创建类的对象,案例如下:首先创建一个普通的Java类Student类,该类位于cn.csdn.reflect包中并编译产生相应的class文件.下面就是该类中各种构造器解剖的方式如下:

//?解析:public?Student()

@Test??//解析无参的构造函数

public?void?test1()?throws?ClassNotFoundException,?SecurityException,

NoSuchMethodException,?IllegalArgumentException,

InstantiationException,?IllegalAccessException,

InvocationTargetException?{

//?1、加载类

Class?cls?=?Class.forName("cn.csdn.reflect.Student");

//?2、通过无参数的构造器解析

Constructor?constructor?=?cls.getConstructor(null);

//?3、创建类的实例

Student?entity?=?(Student)?constructor.newInstance(null);

????????//4、调用对象的方法

entity.study();

//解析:public?Student(String?name,int?age);

@Test??//解析有参的构造函数

public?void?test2()throws?Exception{

//1、加载类

Class?cls?=?Class.forName("cn.csdn.reflect.Student");

//2、通过带有参数的构造器解析

Constructor?constructor?=?cls.getConstructor(String.class,int.class);

//3、创建类实例

Student?entity?=?(Student)constructor.newInstance("redarmy",90);

//4、调用方法

entity.study();

System.out.println(entity.getName());

}

//怎么知道?Student类中有哪些构造器

@Test

public?void?test3()throws?Exception{

//1、加载类

Class?cls?=?Class.forName("cn.csdn.reflect.Student");

//2、获取加载类中的所有的构造器

Constructor?csr[]?=?cls.getConstructors();

//3、遍历构造器csr

for(Constructor?c:csr){

//打印出构造器参数的类型及构造器名称

?System.out.println(c.toGenericString());

}

}

????//解析:public?cn.csdn.reflect.Student(java.lang.String[])

@Test

public?void?test4()throws?Exception{

//1、加载类

Class?cls?=?Class.forName("cn.csdn.reflect.Student");

//2、根据构造器参数类型获取相应的构造器对象????

Constructor?csr?=?cls.getConstructor(String[].class);

String?str[]={"111","123"};

//3、创建实体对象

Student?entity?=?(Student)csr.newInstance((Object)str);

//4、调用方法

entity.study();

}

@Test??//解析私有的构造方法

public?void?test5()throws?Exception{

//1、加载类

Class?cls?=?Class.forName("cn.csdn.reflect.Student");

//2、根据构造器参数类型获取相应的构造器对象????

Constructor?csr?=?cls.getDeclaredConstructor(List.class);

csr.setAccessible(true);//暴力

//3、创建实体对象

Student?entity?=?(Student)csr.newInstance(new?ArrayList());

//4、调用方法

entity.study();

}

}

多学一招:sun公司为简化开发人员创建对象,它在class对象中也提供了一个newInstance方法,用于创建类的对象。这样开发人员可以避免每次都需要去反射Constructor?类以创建对象。

不过需要注意的是:class.newInstance方法内部是反射类无参的构造函数创建的对象,所以利用此种方式创建类对象时,类必须有一个无参的构造函数。

<!--EndFragment-->

读书人网 >编程

热点推荐