时间:2021-05-19
反射
我们先创建一个Student类出来。注意类中的成员变量、构造方法、成员方法公共还是私有
package com.reflect;public class Student { //成员变量 public String name;//公共 private int age;//私有 //构造方法 public Student() { super(); // TODO Auto-generated constructor stub } //私有构造方法 private Student(String name) { this.name = name; } public Student(String name, int age) { super(); this.name = name; this.age = age; } //成员方法(getXxx/setXxx) public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //成员方法 public void study() { System.out.println("我爱学习java!"); } // 私有 private void study(String string) { System.out.println("我还爱学习"+string); } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; }}反射概述
1、反射:反射是通过class文件对象,去使用文件对象的成员方法、构造方法、成员变量
回想之前我们使用对象方法时必须通过new对象去使用。new Student().study(),此时我们就发现了一个问题,小例中我们肯定是知道Student类中是有study()方法的,如果我们想使用用这个类但却不清楚类中的信息,此时反射就起到了一定作用。
其实反射的作用,不止这一点点。如下
2、反射可以提高程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提高硬编码目标类
Java反射技术应用领域很广,后期如软件测试、JavaBean等都有很重要的作用
许多流行的开源框架例如Struts、Hibernate、Spring在实现过程中都采用了该技术
3、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此Java反射机制只要应用在对;灵活性和扩展性要求很高的系统框架上,普通程序不建议使用使用反射会模糊程序内部逻辑:程序员希望在代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。
反射获取Class类对象
一般我们使用第三种
package com.reflect;public class Demo { public static void main(String[] args) throws ClassNotFoundException { // 方式1 Student p = new Student(); Class c = p.getClass(); Student p2 = new Student(); Class c2 = p2.getClass(); System.out.println(p == p2);// false不是同一Student对象 System.out.println(c == c2);// true是同一class对象 // 方式2 Class c3 = Student.class; System.out.println(c == c3);//true是同一class对象 // 方式3 // ClassNotFoundException(类找不到时) Class c4 = Class.forName("com.reflect.Student"); System.out.println(c == c4);//true是同一class对象 }}Class类中相关的几个类
反射获取构造方法
先来认识几个方法
public Constructor getConstructor()// 公共构造方法对象public Constructor[] getConstructors()//所有公共构造方法对象public Constructor[] getDeclaredConstructors()//所有构造方法对象public Constructor getDeclaredConstructor()//获取私有构造方法对象public Constructor<T> getConstructor(Class<?>... parameterTypes)// 参数表示的是:你要获取的构造方法的构造参数个数及数据类型的class字节码文件对象public void setAccessible(boolean flag)// 值为true则指示反射的对象在使用时应该取消Java语言访问检查。 暴力访问package com.reflect;import java.lang.reflect.Constructor;public class ConstructorDemo { public static void main(String[] args) throws Exception { // 获取字节码文件对象 Class c = Class.forName("com.reflect.Student"); // 获取所有构造方法 Constructor[] cons = c.getDeclaredConstructors(); for (Constructor con : cons) { System.out.println(con); } // 获取单个构造方法 Constructor con = c.getConstructor();// 返回的是构造方法对象 Constructor con1 = c.getConstructor(String.class, int.class);// 返回的是有参构造方法对象 Constructor con2 = c.getDeclaredConstructor(String.class); //创建对象 Object obj = con.newInstance(); Object obj1=con1.newInstance("小米",12); // 暴力访问 con2.setAccessible(true);// 值为true则指示反射的对象在使用时应该取消Java语言访问检查。 Object obj2 = con2.newInstance("小白"); System.out.println(obj.toString()); System.out.println(obj1.toString()); System.out.println(obj2.toString()); }}运行结果:
反射获取成员变量
**类比上面Constructor类中的方法,这个类也有同样的方法,获取所有成员变量(返回数组),获取私有成员变量等 这里不再赘述 **
package com.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.Field;/* * 通过发生获取成员变量并使用 */public class FieldDemo { public static void main(String[] args) throws Exception { // 获取字节码文件对象 Class c = Class.forName("com.reflect.Student"); // 获取所有的成员变量 Field[] fields = c.getFields(); Field[] fields1 = c.getDeclaredFields(); for (Field field : fields1) { System.out.println(field); } /* * Person p = new Person(); p.address = "北京"; System.out.println(p); */ // 通过无参构造方法创建对象 Constructor con = c.getConstructor(); Object obj = con.newInstance(); System.out.println(obj); // 获取单个的成员变量 //通过成员变量名 Field nameField = c.getField("name"); // public void set(Object obj,Object value) // 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 nameField.set(obj, "小红"); // 给obj对象的addressField字段设置值为"北京" System.out.println(obj); // 获取age并对其赋值 // NoSuchFieldException 私有变量 Field ageField = c.getDeclaredField("age"); // IllegalAccessException 暴力访问 ageField.setAccessible(true); ageField.set(obj, 18); System.out.println(obj); }}运行结果:
反射获取成员方法
**类比上面Constructor类中的方法,这个类也有同样的方法,获取所有成员方法(返回数组),获取私有成员方法等 这里不再赘述 **
package com.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.Method;public class MethodDemo { public static void main(String[] args) throws Exception { // 获取字节码文件对象 Class c = Class.forName("com.reflect.Student"); // 获取所有的方法 Method[] methods = c.getMethods(); // 获取自己的包括继承父亲的公共方法 Method[] methods1 = c.getDeclaredMethods(); // 获取自己的所有的方法 for (Method method : methods1) { System.out.println(method); } Constructor con = c.getConstructor(); Object obj = con.newInstance(); // 获取单个方法并使用 // public void show() // public Method getMethod(String name,Class<?>... parameterTypes) // 第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型 Method m1 = c.getMethod("study"); // public Object invoke(Object obj,Object... args) // 返回值是Object接收,第一个参数表示对象是谁,第二参数表示调用该方法的实际参数 m1.invoke(obj); // 调用obj对象的m1方法 System.out.println("----------"); Method m2 = c.getDeclaredMethod("study", String.class); // NoSuchMethodException 访问私有方法 暴力访问 m2.setAccessible(true); m2.invoke(obj, "数学"); }}运行结果:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
java反射java从很早的版本开始就引入了反射机制,java如今的框架底层大部分也都是使用反射实现的。这篇博客就去探索下java反射使用的方便之处。要说jav
Java反射机制与动态代理,使得Java更加强大,Spring核心概念IoC、AOP就是通过反射机制与动态代理实现的。1Java反射示例:Useruser=ne
Java中的反射提供了一种运行期获取对象元信息的手段。即正常方法是通过一个类创建对象,反射方法就是通过一个对象找到一个类的信息。Java的反射机制的实现要借助于
Java类反射应用得非常广泛几乎是所有框架的最核心部分,PHP程序员似乎从不关心反射。尝试着用java的思想去理解php的反射,跟java基本上基本一致。参考了
一、java中的反射1.通过反射加载类的属性和方法实例代码:/***java.lang.Class是反射的源头*我们创建了一个类,通过编译(javac.exe)