一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。
构造器的反射
通过构造器解析反射首先要加载类,加载类有以下3种
1、加载类
Class cls = Class.forName("cn.csdn.reflect.Student");
System.out.println(cls);
2、加载类
Student stu = new Student();
Class cls1 = stu.getClass();
System.out.println(cls1);
3、加载类
Class cls2 = Student.class;
System.out.println(Student.class);
构造器解析有:通过无参数的构造器解析和有参数的构造器解析
1、 通过无参数的构造器解析
例:
// 解析: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 student = (Student) constructor.newInstance(null);
4、调用对象的方法
student.study();
}
2、 通过带有参数的构造器解析
例:
//解析: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 student = (Student)constructor.newInstance("redarmy",90);
4、调用方法
student.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){
4、打印出构造器参数的类型及构造器名称
System.out.println(c.toGenericString());
}
}
根据构造器参数类型获取相应的构造器对象
例:String[]
//解析: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();
}
List数组
//解析public cn.csdn.reflect. Student(List list)
@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();
}
注意:在使用clss的newInstance()方法的时候必须确保Student类中有一个无参数的构造器
解剖类
Class对象提供了如下常用方法:
解析公有的成员变量和方法
Public Constructor getConstructor(Class<?>... parameterTypes)
Public Method getMethod(String name, Class<?>... parameterTypes)
Public Field getField(String name) public
解析私有的成员变量和方法
public Constructor getDeclaredConstructor(Class... parameterTypes)
public Method getDeclaredMethod(String name,Class... parameterTypes)
public Field getDeclaredField(String name)
Constructor类提供了如下方法,用于创建类的对象:
public Object newInstance(Object... initargs)
initargs用于指定构造函数接收的参数
在class对象中也提供了一个newInstance方法,用于创建类的对象。这样开发人员可以避免每次都需要去反射Constructor 类以创建对象。
注意:class.newInstance方法内部是反射类无参的构造函数创建的对象,所以利用此种方式创建类对象时,类必须有一个无参的构造函数。
利用Method执行方法
Method对象提供了如下方法,用于执行它所代表的方法:
public Object invoke(Object obj,Object... args)
怎样获取解析类的方法?代码如下:
Class cls=Class.forName("com.csdn.reflect.Student");
Student entity = (Student)cls.newInstance();
Method mds[] = cls.getMethods();
for(Method m:mds){
System.out.println(m.toGenericString());
}
解析:没有参数的public void study方法
Class cls=Class.forName("com.csdn.reflect.Student");
Student student=(Student)cls.newInstance();
Method me=cls.getMethod("study", null);
me.invoke(student, null);
解析:带有参数的public void getSum方法
Class cls = Class.forName("com.csdn.reflect.Student");
Student entity =(Student)cls.newInstance();
Method md = cls.getMethod("getSum", int.class,int.class);
md.invoke(entity, 12,12);
利用Method执行main方法
解析:public static void main(String[] args)
Class cls = Class.forName("com.csdn.reflect.Student");
Student entity =(Student)cls.newInstance();
Method md = cls.getMethod("main", String[].class);
md.invoke(entity,(Object)new String[]{"132","32534"});
利用Field访问属性
Field对象提供了如下方法,用于设置、获取对象属性的值:
public void set(Object obj,Object value)
public Object get(Object obj)
获取成员属性
Class cls=Class.forName("com.csdn.reflect.Student");
Student student =(Student)cls.newInstance();
Field fd[]=cls.getDeclaredFields();
for(Field fld:fd){
System.out.println(fld.getName());
}