.反射概述
JAVA反射机制在执行状态下,对于任一类都可以知道该类的所有属性和方法; 对于任何对象,都可以调用其方法和属性之一。 这种动态检索的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要解剖类,必须首先获取该类的字节码文件对象。 因为解剖使用的是Class类的方法,所以首先要获取与每个字节码文件对应的Class类型的对象。
反射是一种java语言机制,允许动态实例化对象、读/写属性和调用方法
.反射强的地方:
反射机制没有限制,可以知道任何类的所有属性和方法,也可以对任何对象调用其任何方法和属性。
示例:
*为什么要在jdbc连接中使用class.forname (com.JDBC.MySQL.driver ); mysql驱动程序驱动程序、Oracle驱动程序或其他驱动程序
必须实现jdbc的驱动程序接口。 * com.JDBC.MySQL.driverextendsjava.SQL.driver * Java.SQL.driverd=class.forname (com.JDBC.MySQL.driver
*示例: *
* xxx
* com.XXX.XXX servlet
*
. * com.XXX.xxxservletextendshttpservlet * com.XXX.XXX servlet路径* class c LZ=class.forname (* http servlet http服务器只要获得班级的对象,什么都做得到
与所有反射相关的代码都从获取类(java.lang.Class )对象开始
1 Class.forName (完整类名) jdbc,用于自定义mvc框架
类名. class可以用作通用查询
3对象. getClass ()可以通用添加/删除/更改
注1:ClassNotFoundException ((类名错误|较少的jar包) ) )
注2 :同一类中只创建一个类对象
测试类信息:
packagecom.yuan.reflect; 公共类student {隐私保护sid; 私有字符串名称; 公共集成器Age; 静态{
system.out.println ('加载到JVM中!' );
}publicStudent () {super );
System.out.println;
}公共student (strings id ) {super ); this.sid=sid;
System.out.println;
}公共student (strings id,String sname ) {super ); this.sid=sid; this.sname=sname;
System.out.println;
}
@suppresswarnings(unused ) (私有) integerage ) )
System.out.println; this.age=age;
}publicString getSid () {returnsid;
}公共语音设置(strings id ) {this.sid=sid;
}公共字符串gets name (() {returnsname;
} publicvoidsetsname (strings name ) {this.sname=sname;
公共语音助手() {
System.out.println ('你好! 我是' this.sname;
公共语音助手(字符串名称) {
system.out.println(Name '你好! 我是' this.sname;
}
@suppresswarnings(unused ) ) privateInteger bdd ) integera,Integer b ) ) returnnewinteger ) b.intValue ) b.intValue
}
>@OverridepublicString toString() {return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + "]";
}
}
1、Class.forName("类的全路径名");
Class clz = Class.forName("com.yuan.reflect.Student");
System.out.println(clz);
结果:
class com.yuan.reflect.Student
2、类名.class
Class clz=Student.class;
System.out.println(clz);
结果:
class com.yuan.reflect.Student
3、类(Class类类的类对象) 实例.getClass() 通用增删改可用
Student stu=newStudent();
Class clz=stu.getClass();
System.out.println(clz);
结果:
class com.yuan.reflect.Student
.反射的三大作用
1. 实例化对象 .newInstance();
代码:
packagecom.yuan.reflect;importjava.lang.reflect.Constructor;/*** 反射实例化
* 1.能够实例化未知的类
* 2.能够通过私有的构造器创建实例
*@author***
**/
public classDemo2 {public static void main(String[] args) throwsException {
Class clz= Student.class;//1、反射调用无参构造方法创建了一个学生对象
// Student stu=(Student)clz.newInstance();//2、调用一个有参构造方法创建一个学生对象//拿到构造器类//Constructor con = clz.getConstructor(String.class);//返回一个构造器// //通过构造器实例化对象//Student stu = (Student)con.newInstance("s007");//System.out.println(stu);//3、调用两个有参构造方法创建一个学生对象//拿到构造器类//Constructor con = clz.getConstructor(String.class,String.class);//返回一个构造器// //通过构造器实例化对象//Student stu = (Student)con.newInstance("s007","zhangsna");//System.out.println(stu);//4、调用Student类私有的构造方法创建了一个学生对象//#java.lang.NoSuchMethodException: 未找到该方法(因为方法私有化所以不可被调用)//# getConstructor 这个方法只能寻找到public(公开的)修饰的构造器//Constructor con = clz.getConstructor(Integer.class);//# getDeclaredConstructor 此方法可以寻找到任何修饰符修饰的构造器//Constructor con = clz.getDeclaredConstructor(Integer.class);//# 设置私有方法可被访问//con.setAccessible(true);// //通过构造器实例化对象//Student stu = (Student)con.newInstance(17);//System.out.println(stu);
}
}
结果1:
结果2:
结果3:
结果4:
出现错误1:java.lang.NoSuchMethodException ,说明你用的是getConstructor()方法,换成getDeclaredConstructor();
出现错误2: java.lang.IllegalAccessException 没有设置私有可访问,加 .setAccessible(true);
这两种都是针对于获取私有方法时找不到方法会出现的错误
2. 动态调用方法 .invoke
public static void main(String[] args) throwsException {
Student stu=newStudent();//stu.hello();//普通调用方法
Class clz=stu.getClass();//调用无参方法//Method m = clz.getDeclaredMethod("hello");//m.invoke(stu);//调用带参方法
Method m = clz.getDeclaredMethod("add",Integer.class,Integer.class);
m.setAccessible(true);//invoke 如果反射动态调用的方法是被void所修饰,他返回的就是null//如果反射动态调用的方法不是被void所修饰,那么返回的就是被调用的方法的返回值
Object o=m.invoke(stu,20,5);
System.out.println(o);
}
结果:
3 .读写属性 set/get
packagecom.yuan.reflect;importjava.lang.reflect.Field;/*** 反射属性赋值取值
*
* 反射能将jsp传递过来的参数直接封装到实体类中
*
*@author***
**/
public classDemo4 {public static void main(String[] args) throwsException{
Student stu=new Student("s008","lili");//stu.setSid("s004");
stu.age=22;//System.out.println(stu);
// 赋值//反射处理的是一类的问题,在处理多个属性赋值或取值的时候,使用反射可以减省很多代码//处理私有(private)属性时 需要设置它为可被访问: setAccessible(true);
Class clz=stu.getClass();
Field field= clz.getDeclaredField("sid");//被赋值的属性
field.setAccessible(true);//设置私有可被访问
field.set(stu, "s02");//属性赋值
System.out.println(stu);
System.out.println(field.get(stu));
//取值//Field[] fields = clz.getDeclaredFields();//for (Field field : fields) {//field.setAccessible(true);//System.out.println(field.getName()+"--"+field.get(stu));//}
}
}
赋值结果:
加载进jvm中!
调用两个参数的构造方法创建了一个学生对象
Student [sid=s02, sname=lili, age=22]
s02
取值结果:
加载进jvm中!
调用两个参数的构造方法创建了一个学生对象
sid--s008
sname--lili
age--22
.访问修饰符 getModifiers()
测试类信息:
public classStudent {privateString sid;privateString sname;publicInteger age;
}
测试代码:
public static voidmain(String[] args) {
Class clz=Student.class;
Field[] fields=clz.getDeclaredFields();for(Field field : fields) {
System.out.println("-->");
System.out.println(Modifier.toString(field.getModifiers()));
}
}
输出结果:
-->private
-->private
-->public
谢谢观看!^-^