什么是反射?
反射可以在运行时动态加载类,创建对象。这种类和对象在编译期间都是不确定的,只有在运行到对应的反射代码才能确定下来。反射还可以获取对象自身的信息,包括属性、方法等,并且可以打破访问修饰符的限制,设置并访问私有的属性,获取并调用私有的方法。
通过反射加载类
反射,最刚开始接触其实是在jdbc的学习中。
看下面获取mysql连接的代码
//反射加载mysql驱动
Class.forName(“com.mysql.jdbc.Driver”);
String url = “jdbc:mysql://localhost:3306/test?user=root&password=123456″;
Connection con = DriverManager.getConnection(url);
Class.forName用来加载com.mysql.jdbc.Driver这个驱动类,并且返回Class对象,但是这里并没有去接收它的返回值,那么DriverMannger是如何得到这个驱动类的呢?
看下com.mysql.jdbc.Driver的实现就知道了
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
可以看到mysql驱动类中有这一段静态块,在加载驱动类时,初始化的阶段会执行静态块里的代码,加载驱动类到DriverManager.
此外对于Class.forName需要了解一点就是,通过调用方的类加载器反射加载该类。
通过反射创建对象
Class clazz = Class.forName("com.domain.Person");
//创建对象,注意必须要有空构造器
Object obj = clazz.newInstance();
//两种方法判断某个对象时某一个类的对象
System.out.println(obj instanceof Person);
System.out.println(clazz.isInstance(obj));
通过反射获取对象的域
Class clazz = Class.forName("com.domain.Person");
Object obj = clazz.newInstance();
//可获取到私有域
//getField只可获得公开域
Field field = clazz.getDeclaredField("name");
//私有域 可以设置为可以访问,打破访问修饰符的访问控制权限
field.setAccessible(true);
//为obj的name属性设置值 yang
field.set(obj,"yang");
//获取输出