今天本人给大家讲解一下Java的反射基础技术,如有不对的或者讲的不好的可以多多提出,我会进行相应的更改,先提前感谢提出意见的各位了!!!
反射它是根据字节码文件可以反射出类的信息、字段、方法、构造方法等内容,还可以创建对象调用方法,我们称它为反射技术。
它有三种方法,1.通过Class获取类对象
2.通过getClass()方法获取类对象
3.通过Class.forName(“完整类名”)获取类对象
Class c1 = ReflectionBasic.class; Class c2 = new ReflectionBasic().getClass(); Class c3 = Class.forName("reflection.getClassObject.ReflectionBasic"); System.out.println(c1); System.out.println(c2); System.out.println(c3);
运行结果:
注意: Class.forName()它除了能获取Class对象,还可以将获取的类对象自动加载到JVM虚拟机的内存中去 ,下面案例的运行结果可以看出代码输出的static静态代码块一个泛型的C4和C5对象,可是只有C5输出了static,这就说明了使用Class.forName()可以将类对象加载到JVM虚拟机的内存中去。
//通过输出OtherTest反射对象 Class<?> c4 = OtherTest.class; System.out.println("此输出对象是C4==============================="+c4); Class<?> c5 = Class.forName("reflection.getClassObject.OtherTest"); System.out.println("此输出对象是C5==============================="+c4); class OtherTest{ static { System.out.println("你好呀!!!宝宝们!!!"); } }
运行结果:
在java.lang.reflect包下有很多反射类信息的类
反射类的信息
接口类:
public interface IReflection { }
父类:
public class Reflection { }
主类:
public class ReflectionInfo extends Reflection implements IReflection { public static void main(String[] args) { //创建类的对象 Class<?> c1 = ReflectionInfo.class; //获取反射ReflectionInfo类的================================修饰符 int modifiers = c1.getModifiers();//得到的是一个整数那么我们就需要转换了 System.out.println(modifiers); String sModifiers = Modifier.toString(modifiers);//转换后得到的信息 System.out.println(sModifiers); System.out.println("以上是获取反射ReflectionInfo类的================================修饰符"); //获取反射ReflectionInfo类的================================完整类名 String name = c1.getName(); System.out.println(name); //获取反射ReflectionInfo类的================================简易类名 String simpleName = c1.getSimpleName(); System.out.println(simpleName); System.out.println("以上是获取反射ReflectionInfo类的================================完整类名和简易类名"); //获取反射ReflectionInfo类的================================完整父类名 Class<?> superclass = c1.getSuperclass(); System.out.println(superclass.getSuperclass()); //获取反射ReflectionInfo类的================================简易父类名 System.out.println(superclass.getSimpleName()); System.out.println("以上是获取反射ReflectionInfo类的================================完整父类名和简易父类名"); //获取反射ReflectionInfo类的================================接口,由于接口可以是多个我们需要通过遍历来输出出来 Class<?>[] interfaces = c1.getInterfaces(); if(interfaces.length>0){ for (int i = 0; i < interfaces.length;i++){ //获取反射ReflectionInfo类的================================完整接口名 System.out.println(interfaces[i]); //获取反射ReflectionInfo类的================================简易接口名 System.out.println(interfaces[i].getSimpleName()); } } } }
运行结果:
错误案例: 通过getFile()方法得到private属性的值,会报错
public class AccessFiled { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException { //创建Class对象 Class<?> c1 = Company.class; //返回返回的公共字段public Field field = c1.getField("name"); //通过反射技术创建对象实例,默认调用无参构造哦 Object obj = c1.newInstance();//此方法相当于new一个Company对象 field.set(obj,"无名公司"); //设置name的字段值 System.out.println(obj); System.out.println(field.get(obj));//输出name的字段值 //返回返回的公共字段public Field fields = c1.getField("id"); //通过反射技术创建对象实例,默认调用无参构造哦 field.set(obj,"00001"); //设置name的字段值 System.out.println(field.get(obj));//输出name的字段值 } } class Company{ public String name; private int id; }
运行结果:
正确案例:使用getDeclaredField()方法得到private修饰的id值,这个是可以得到任意修饰符修饰的字段
public class AccessFiled { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException { //创建Class对象 Class<?> c1 = Company.class; //返回返回的公共字段public Field field = c1.getField("name"); //通过反射技术创建对象实例,默认调用无参构造哦 Object obj = c1.newInstance();//此方法相当于new一个Company对象 field.set(obj,"无名公司"); //设置name的字段值 System.out.println(obj); System.out.println(field.get(obj));//输出name的字段值 //返回返回的公共字段public Field fields = c1.getDeclaredField("id"); //通过反射技术创建对象实例,默认调用无参构造哦 field.set(obj,"00001"); //设置name的字段值 System.out.println(field.get(obj));//输出name的字段值 } } class Company{ public String name; private int id; }
运行结果:
public class CallObject { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { //创建Class对象 Class<?> c1 = Company.class; //反射shou()方法 Method method = c1.getMethod("show", null);//前面的参数是方法名。后面的是方法的返回值类型 //通过反射创建实例 Object obj = c1.newInstance(); System.out.println("无参==========="+method.invoke(obj,null )); System.out.println(obj); Method shous = c1.getMethod("shows",String.class); shous.invoke(obj,"无名公司"); //反射shows()方法带(参数列表类型) System.out.println("有参==========="+obj);; } } class Company{ public String name; private int id; public void show(){ System.out.println("show=====方法"); } public void shows(String name){ System.out.println("shows======方法"); this.name = name; } @Override public String toString() { return "Company{" + "name='" + name + '/'' + ", id=" + id + '}'; } }
运行结果:
Java的反射基础讲解完毕,又不懂或者不理解的可以在评论区给本人留言,我会及时回复大家的。