Java在真正需要使用一个类是才会加载类,而不是在程序启动时就加载所有类。因为大部分用户只是使用到应用程序的部分资源,在需要某些功能时才加载某些资源,可以让系统的资源运用更有效率。使用反射机制,可以在运行时期动态加载类并生成对象,操作对象上的方法,改变类成员的值,甚至连私有成员的值也可以改变。
先创建一个javabean
package com.reflect.bean;
public class Student {
private int sid;
private int sage;
private String sname;
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public int getSage() {
return sage;
}
public void setSage(int sage) {
this.sage = sage;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Student(){
}
public Student(int id, int age, String name) {
super();
this.sage = id;
this.sid = age;
this.sname = name;
}
}
一、应用反射API获取类的信息,包括类的名字、构造器、属性、方法
package com.reflect.test;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/*
* 应用反射API获取类的信息,包括类的名字、构造器、属性、方法
*/
public class Demo1 {
public static void main(String args[]){
String path = "com.reflect.bean.Student";
//载入Student
try {
Class clazz = Class.forName(path);
//获取类名
System.out.println(clazz.getName());//得到的是 com.reflect.bean.Student
System.out.println(clazz.getSimpleName());//得到的是 Student
//获取属性
Field[] fields1 = clazz.getFields();//只能获取public的属性
Field[] fields2 = clazz.getDeclaredFields();//可获取所有属性
Field field = clazz.getDeclaredField("sname");//获取sname属性
//获取方法
Method[] methods1 = clazz.getDeclaredMethods();//获取所有方法
Method method = clazz.getDeclaredMethod("setSname", String.class);//获取setSname方法
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
二、通过反射API动态构造:构造器、方法、属性
package com.reflect.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.reflect.bean.Student;
/*
* 通过反射API动态构造:构造器、方法、属性。
*/
public class Demo2 {
public static void main(String[] args) {
String path = "com.reflect.bean.Student";
try {
Class clazz = Class.forName(path);
/***************通过动态调用方法,创建对象***************/
Student stu1 = (Student) clazz.newInstance();//调用了Student的无参构造方法
//调用Student指定的的构造方法
Constructor<Student> constructor = clazz.getDeclaredConstructor(int.class,int.class,String.class);
Student stu2 = constructor.newInstance(101,20,"李明");
System.out.println(stu2.getSname());//输出:李明
/****************通过反射API,操作属性****************/
Student stu4 = (Student) clazz.newInstance();
Field field = clazz.getDeclaredField("sname");
field.setAccessible(true);//因为sname为private,所以需将setAccessible设置为true,表示该属性可以直接访问,无需做安全检查
field.set(stu4, "王五");
System.out.println(stu4.getSname());//输出:王五
System.out.println(field.get(stu4));//输出:王五
/****通过反射API,调用普通方法,比如调用 setSname************/
Student stu3 = (Student) clazz.newInstance();
//setSname,方法1
stu3.setSname("张三");
System.out.println(stu3.getSname());//输出:张三
//setSname,方法2
Method method = clazz.getDeclaredMethod("setSname", String.class);
method.invoke(stu3, "张三1");
System.out.println(stu3.getSname());//输出:张三1
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}