反射就是把Java类中的各种成分映射成响应的java类
反射的原理
应用在一些通用性高的代码中后面学到的框架,大多数都是使用反射来实现的
在框架开发中,都是基于配置文件开发
在配置文件中配置了类,可以通过反射得到类中的 所有内容,
可以让类中的某个方法来执行
类中的所有内容:属性、无参的构造方法、有参的构造方法、普通方法
原理:
1.首先需要把java文件保存到本地硬盘 .java格式
2.编译java文件 成 .class文件
3.使用jvm,把class文件通过类加载加载到内存中
万事万物皆对象,class文件在内存中使用Class类表示
当使用反射的时候,首先需要获取到Class类,得到这个类之后,
就可以得到class文件里面的所有内容
属性通过一个类 Field
构造方法通过一个类 Constructor
普通方法通过一个类 Method
获取Class类的三种方式(得到类的实例的字节码):
Class clazz1 = Person.class;
Class clazz2 = new Person().getClass();
Class clazz3 = Class.forName("cn.itcast.test01.Person");
使用反射操作无参的构造方法:
如果要对一个类进行实例化,可以new,不使用new,怎么获取?
-//得到Class
Class c3 = Class.forName("cn.itcast.test09.Person");
//得到Persond类的实例
Person p =(Person)c3.newInstance();
使用反射操作有参的构造方法:
-//得到Class
Class c3 = Class.forName("cn.itcast.test09.Person");
//传递的是有参构造方法里面参数类型,类型使用class形式传递
Constructor cs = c3.getConstructor(String.class,String.class);
//通过有参数的构造方法创建Person实例
Person p1 = (Person)cs.newInstance("lisi","100");
使用反射操作属性:
-//得到Class
Class c3 = Class.forName("cn.itcast.test09.Person");
//得到Persond类的实例
Person p =(Person)c3.newInstance();
//得到name属性,参数是属性名称,就算是私有的也可以获得,但是暂时不能使用
Field f1 = c3.getDeclaredField("name");
//设置可以操作私有属性,此时就可以使用了。
f1.setAccessible(true);
//设置name值
f1.set(p,"wangwu");//前一个是对象,后一个是值
使用反射操作普通方法:
-//得到Class
Class c3 = Class.forName("cn.itcast.test09.Person");
//得到Persond类的实例
Person p =(Person)c3.newInstance();
//得到普通方法
Method m1 = c3.getDeclaredMethod("setName",String.class);
//执行普通方法
m1.invoke(p4,"zhaoliu");//第一个参数是Person实例,第二个参数是设置的值
当操作的方法是静态的方法的时候,因为静态方法调用的方式是 类名.方法名,不需要类的实例
所以,使用反射操作静态方法的时候,也是不需要实例的。
-m1.invoke(null,"zhaoliu");
用反射的方式执行某个类中的main方法
启动java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个
main方法时,如何为invoke方法传递参数呢?按照jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素
对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac到底会按照哪种语法进行处理呢?
jdk1.5肯定要兼容jdk1.4的语法,会按照jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。所以,在给main方法
传递参数时,不能使用代码:mainMethod.invoke(null,new String[]{"xxx"}),javac只会把它当作jdk1.4的语法进行理解,
而不把它当作jdk1.5的语法解释,因此会出现参数类型不对的问题。
解决办法:
mianMethod.invoke(null,new Object[]{new String[]{"xxx"}});
mainMethod.invoke(null,(Object)new String[]{"xxx"});