一、背景
1.首先我们得知道反射是什么东西、它的使用原理是什么、它有什么实际的用处、解决完这一系列的为什么我觉着大家应该就差不多明白了这到底是个什么玩意儿。下面我就来详细的讲讲反射这个东西,希望能帮助你们加深对它的理解。
二、反射是什么
1.JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
三、反射的原理是什么
1.一张图片告诉你反射的原理以及发生的时间和过程:
借鉴的:https://blog.csdn.net/lwl20140904/article/details/80163880他的图片。说白了反射就是通过得到class字节码,反向获取Student对象的各种信息。
四、简单实例
1.测试例子
package com.tydic.reflection.demo;
interface Fruit {
public void eat() ;
}
class Apple implements Fruit{
public void eat() {
System.out.println("Apple...");
}
}
class Orange implements Fruit{
public void eat() {
System.out.println("Orange...");
}
}
class Factory{
public static Fruit getInstance(String className){
Fruit fruit = null ;
try{
fruit = (Fruit) Class.forName(className).newInstance() ;
}catch(Exception e ){
e.printStackTrace() ;
}
return fruit ;
}
}
public class FactoryTest{
public static void main(String args[]){
//传入完整的包.类名称
Fruit f = Factory.getInstance("com.tydic.reflection.demo.Apple") ;
if(f!=null){
f.eat() ;
}
}
}
2.结果:Apple...
3.如果不用反射,那么我们如果再加一个西瓜类,就得在Factory里判断,每添加一个类都要修改一次Factory,但用了反射只用在调用的时候传入完整的类名就可完成。结果:用反射,修改一处代码;不用反射,修改两处代码。
五、其他的获取方式
1、通过Class.forName()方法加载字符串,就可以得到该字符串做代表的Class对象。
例如:Class<?> clazz = Class.forName("java.lang.String")就可以得到String类的Class对象。值得注意的是,字符串必须是类的全名,即包名+类名。Class.forName("")返回的是类,Class.forName("").newInstance()返回的是object对象。
2、通过类名调用class属性得到该类的Class对象。
例如:Class<?> clazz = String.class也可以得到String类的Class对象。
3、调用实例的getClass()方法。
例如:Date date = new Date();
Class<?> clazz = date.getClass();
通过上边的两句代码就可以得到date实例的Class对象。
4、如果是基本类型的包装类,则可以通过调用包装类的Type属性来获得该包装类的Class对象。
例如:Class<?> clazz = Integer.TYPE;
六、结束
上面就是我对反射的简单理解,如有不足,请各位指点。