1. 参考
建议按顺序阅读以下文章
学了这么久的java反射机制,你知道class.forName和classloader的区别吗?
Java反射(超详细!)
2. 实战
2.1 通过Class.forName()方法获取字节码
这个方法会去我们的操作系统寻找这个class文件(java编译生成的字节码文件),并将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。注意这里的静态块指的是在类初始化时的一些数据。
public class User {
private static int a = 10;
{
System.out.println("普通代码块");
}
static{
System.out.println("静态变量a:"+a);
System.out.println("静态代码块");
}
}
// 测试
public class FDDTest {
public static void main(String[] args) {
try {
Class forNameUser = Class.forName("com.fdd.reflect.User");
System.out.println("Class.forName testing...");
System.out.println("user " + forNameUser.getName());
} catch (ClassNotFoundException e){
e.printStackTrace();
}
}
}
/**
静态变量a:10
静态代码块
Class.forName testing...
user com.fdd.reflect.User
*/
2.2 创建对象。
class ReflectTest02{
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
// 通过反射机制,获取Class,通过Class来实例化对象
Class c = Class.forName("javase.reflectBean.User");
// newInstance() 这个方法会调用User这个类的无参数构造方法,完成对象的创建。
// 重点是:newInstance()调用的是无参构造,必须保证无参构造是存在的!
Object obj = c.newInstance();
System.out.println(obj);
}
}
2.3 获取并调用属性Field
class ReflectFieldQuery{
public static void main(String[] args) throws ClassNotFoundException {
// 反射机制创建对象
Class studentClass = Class.forName("javase.reflectBean.Student");
//获取所有的属性
Field[] fields = studentClass.getDeclaredFields();
for (Field f : fields){
// 获取属性的修饰符列表,返回的修饰符是一个数字,每个数字是修饰符的代号
// 用Modifier类的toString转换成字符串
String modifiers = Modifier.toString(f.getModifiers());
// 获取属性的类型
String typeName = f.getType().getSimpleName();
// 获取属性的名字
String fieldName = f.getName();
}
}
}
class ReflectFieldUpdate{
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
//使用反射机制给属性赋值
Class studentClass = Class.forName("javase.reflectBean.Student");
Object obj = studentClass.newInstance();
Field nameField = studentClass.getDeclaredField("name");
// 打破封装(反射机制的缺点:打破封装,可能会给不法分子留下机会!!!)
// 这样设置完之后,在外部也是可以访问private的。
nameField.setAccessible(true);
nameField.set(obj, "liming");
System.out.println(nameField.get(obj));
}
2.4 获取并调用方法Method
class ReflectMethodQuery{
public static void main(String[] args) throws ClassNotFoundException {
Class userServiceClass = Class.forName("java.lang.String");
// 获取所有的Method(包括私有的!)
Method[] methods = userServiceClass.getDeclaredMethods();
for (Method m : methods){
String modifiers = Modifier.toString(m.getModifiers());
String returnTypeName = m.getReturnType().getSimpleName();
String methodName = m.getName();
Class[] parameterTypes = m.getParameterTypes();
}
}
}
// 重点:必须掌握,通过反射机制怎么调用一个对象的方法?五颗星*****
class ReflectMethodInvoke{
public static void main(String[] args) throws Exception {
//使用反射机制调用方法
Class userServiceClass = Class.forName("javase.reflectBean.UserService");
// 创建对象
Object obj = userServiceClass.newInstance();
// 获取Method
Method loginMethod = userServiceClass.getDeclaredMethod("login", String.class, String.class);
Object resValues = loginMethod.invoke(obj, "admin", "123");//注:方法返回值是void 结果是null
System.out.println(resValues);
}
}
2.5 获取并调用构造器Constructor
class ReflectConstructorQuery{
public static void main(String[] args) throws ClassNotFoundException {
Class vipClass = Class.forName("javase.reflectBean.Vip");
Constructor[] constructors = vipClass.getDeclaredConstructors();
for (Constructor c : constructors){
String modifiers = Modifier.toString(c.getModifiers());
String returnTypeName = c.getReturnType().getSimpleName();
String methodName = c.getName();
Class[] parameterTypes = c.getParameterTypes();
}
}
}
class ReflectConstructorInvoke{
public static void main(String[] args) throws Exception {
Class vipClass = Class.forName("javase.reflectBean.Vip");
// 调用无参数构造方法
Object obj1 = vipClass.newInstance();//Class类的newInstance方法
Constructor c1 = vipClass.getDeclaredConstructor(int.class, String.class, String.class, boolean.class);
Object obj2 = c1.newInstance(321, "lsi", "1999-10-11", true);
System.out.println(obj2);
// 获取无参数构造方法
Constructor c2 = vipClass.getDeclaredConstructor();
Object obj3 = c2.newInstance();
System.out.println(obj3);
}
}
附录
Class类方法
Field类方法
Method类方法
Constructor类方法