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();// 获取MethodMethod loginMethod = userServiceClass.getDeclaredMethod("login", String.class, String.class);Object resValues = loginMethod.invoke(obj, "admin", "123");//注:方法返回值是void 结果是nullSystem.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类方法