1.反射的作用
通过java语言中的反射机制可以操作字节码文件(可以读和修改字节码文件)
2.反射机制的相关类在java.lang.reflect.*;
反射机制相关的类(重要的类):
java.lang.Class; //代表字节码文件
java.lang.reflect.Method; //代表字节码中的方法字节码
java.lang.reflect.Constructor; //代表字节码中的构造方法字节码
java.lang.reflect.Filed //代表字节码中的属性字节码
3.要操作一个字节码需要先获取到这个类的字节码,有三种方式获取:
(1)Class.forName()
静态方法,方法的参数是一个字符串,字符串需要的是一个完整类名,完整类名必须带有包名.
(2)java中任何一个对象都有一个方法:getClass()
示例:
String s = “abc”;
Class x = s.getClass();//代表xString.class字节码文件,s代表String类型
(3)java语言中任何一种类型,包括基本数据类型,它都有.class属性
Class z = String.class
4.获取类路径下的绝对路径
src是类的根路径
1.java.util包下提供了一个资源绑定器,便于获取属性配置文件中的内容,使用这种方式时,属性配置文件xxx.properties必须放到类路径下(即src下)
代码示例: ResourceBundle bundle = ResourceBundle.getBundle("文件名");//文件名不需要后缀 String className = bundle.getString("className");
2.获取Field(Field译为字段,其实就是属性/成员)
使用反射机制获取
代码示例: //获取整个类 Class studentClass = Class.forName("完整类名"); //获取类中所有的Field(public修饰的) Field[] fields = studentClass.getFields(); //获取类中所有的Field(包括public、protected、private等都可以) Field[] fields = studentClass.getDeclareFields(); //获取属性的类型 field.getType(); //获取属性的修饰符列表 field.getModifiers();//返回的修饰符是一个数字,每个数字是修饰符的代号 //将这个“代号”数字转换成“字符串” String modifierString = Modifier.toString(i);
代码示例: /* java.lang.reflect.Field;类中的属性 */ import java.lang.reflect.*; public class Test09 { public static void main(String[] args) throws Exception{ //获取整个类 Class c = Class.forName("java.lang.String"); //获取所有的属性 Field[] fs = c.getDeclaredFields(); StringBuffer sb = new StringBuffer(); sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() + "{\n"); for(Field field:fs){ sb.append("\t"); sb.append(Modifier.toString(field.getModifiers()) + " "); sb.append(field.getType().getSimpleName() + " "); sb.append(field.getName() + ";\n"); } sb.append("}"); System.out.println(sb); } }
代码示例: Class studentClass = Class.forName("完整类名"); Objcet obj = studentClass.newInsrance(); //obj就是Student对象,底层调用无参数构造方法 //获取指定属性 Field noField = studentClass.getDeclareField("属性名"); //给obj对象(student对象)的属性赋值 noField.set(obj,111);//给obj对象的属性赋值111 //可以访问私有属性:打破封装 nameField.setAccessible(true); //这样设置以后在外部可以访问private了
反射机制的缺点:打破封装,可能会给不法分子留机会
1.int…cargs,这就是可变长度参数
2.可变长度参数要求的个数是0~N个,可变长度参数在参数列表中必须在最后一个位置上,而且可变长度参数只能有1个
3.可变长度参数可以当做一个数组来看待
代码示例: //获取类 Class studentClass = Class.forName("完整类名"); //创建对象 Object obj = userService.newInstance(); //获取Method Method loginMethod = userServiceClass.getDeclareMethod("login",String.class,String.class); //调用方法 Object reValue = loginMethod.invoke(obj,"admin","123");
反射机制让代码具有通用性,可变化的内容都是写到配置文件中,将来修改配置后,创建的对象不一样,调用方法不同,但java代码无需做任何改动。
1.先获取到这个有参数的构造方法
Class c = Class.forName(“完整类名”);
Constructor con = c.getDeclaredConstructor(参数类型.class);
2.调用构造方法new对象
con.newInstance(实际参数);
//获取无参构造方法
Constructor con = c.getDeclaredConstructor();
Object newObj2 = con2.newInstance();