Java笔记-反射
在程序运行过程中,可以通过动态类名获取对象内部的成员变量和方法。
public static void main(String[] args){
Student stu = new Student();
Class cls = stu.getClass();//方式一:通过getClass()
Class cls1 = Class.forName("");//方式二:通过Class.forName();
Class cls2 = Student.class;//方式三:通过类.class
//三者的hashCode都一致
}
一个加载的类在JVM中只会有一个Class实例
一些Class类的方法
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException, NoSuchFieldException {
User user = new User();
Class cls = user.getClass();
/*构造一个对象
Class cls = Class.forName("com.cc.entity.User");
User user = (User)cls.newInstance();
*/
System.out.println(cls);
System.out.println("获得包名+ 类名" + cls.getName());
System.out.println("================获得属性=============");
Field[] fields = cls.getDeclaredFields();
for(Field m : fields){
System.out.println(m.getName());
}
Method[] methods1 = cls.getDeclaredMethods(); // 获得本类和继承类的方法
System.out.println("================获得本类的方法=============");
Method[] methods = cls.getDeclaredMethods();
for(Method m : methods){
System.out.println(m.getName());
}
System.out.println("================执行方法=============");
Method method = cls.getMethod("run");
method.invoke(user);
Method setName = cls.getMethod("setName", String.class);
setName.invoke(user,"zhang");
Method getName = cls.getMethod("getName");
System.out.println(getName.invoke(user));
Field name = cls.getDeclaredField("name");
name.setAccessible(true);//name为private权限,不能直接设置,需要设置access为通过
name.set(user,"小张");
System.out.println(user);
}
执行结果:
使用场景
- JDBC连接数据库,Class.forName();
- Spring框架等使用反射机制,例如Spring 通过 XML 配置模式装载 Bean 的过程
优点和缺点
优点: 可以动态创建对象和编译,提高代码灵活性、
缺点:反射是一种解释操作,会慢与直接执行的操作,性能不好