反射
1、反射(Reflection):是Java被视为“动态”语言的关键,反射机制允许在执行期间借助于Reflection的API取得任何类(接口)的内部信息,并能直接操作任意对象的内部信息。
2、Java反射机制主要提供了以下功能:
(1)在运行时构造任意一个类的对象
(2)在运行时获取任意一个类所具有的成员变量和方法
(3)在运行时调用任意一个对象的方法(属性)
(4)生成动态代理
3、获得Class 类的三种方式:
(1)类名.Class 如:Person.Class
(2)实例名.getClass() Person person = new Person(); person.getClass();
(3)Class.forName("全类名"); Class.forName("com.jdbc.mysql.Driver");
package _18反射.d1; public class Student { String name;//姓名 int age;//年龄 public Student() {} public Student(String name, int age) {this.name = name;this.age = age;} 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;} }
package _18反射.d1; /**获取class类 * @author Lx * @create 2024-03-19 21:29 * 获取class类的三种方式: * (1)类名.class; * (2)实例名.getClass(); * (3)Class.forName("全类名"); */ public class GetClassTest { public static void main(String[] args) throws ClassNotFoundException { //1类名.class() //Class c1=Student.class; System.out.println(Student.class); //2、实例名.getClass(); Student stu=new Student(); System.out.println(stu.getClass()); //3、Class.forName("全类名") Class c3=Class.forName("_18反射.d1.Student"); System.out.println(c3); } }
4、利用反射获取属性的值
package _18反射.d2; /** * @author Lx * @create 2024-03-19 21:28 */ public class Student { public String name;//姓名 private int age;//年龄 private String add;//地址 public Student() { } public Student(String name, int age,String add) {this.name = name;this.age = age;this.add=add; } 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 String getAdd() {return add;} public void setAdd(String add) {this.add = add;} }
获取公共属性的值和私有化属性的值:
package _18反射.d2; import java.lang.reflect.Field; /** * @author Lx * @create 2024-03-19 22:03 * 获取 */ public class GetFieldTest { public static void main(String[] args) { test1(); test2(); } //获取公共属性name的值 public static void test1(){ try { //1、获取JVM中的class Class c=Class.forName("_18反射.d2.Student"); //2、通过class取属性,公共属性name Field field=c.getField("name"); //3、通过属性调值(得先有对象) Student stu=new Student("张三",18,"云南");//定义去属性name依赖的对象stu System.out.println(field.get(stu));//调属性name的值 } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } //获取私有化属性age的值 public static void test2(){ try { //1、加载并取到class Class c=Class.forName("_18反射.d2.Student"); //2、通过class取到属性(字段),取私有化的age Field field=c.getDeclaredField("age"); //System.out.println(field); //3、获取属性的值,得先有对象 Student stu=new Student("李四",19,"贵州"); //设置field对象的可访问性,否则取不到私有化的age值 field.setAccessible(true); System.out.println(field.get(stu)); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }
5、利用反射获取方法
package _18反射.d3; /** * @author Lx * @create 2024-03-19 21:28 */ public class Student { public String name;//姓名 private int age;//年龄 private String add;//地址 public Student() { } public Student(String name, int age, String add) { this.name = name; this.age = age; this.add=add; System.out.println("执行了有参构造方法"); } 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 String getAdd() { return add; } public void setAdd(String add) { this.add = add; } //普通方法 public void show(){ System.out.println("这是无参数的方法"); } public void show(String str){ System.out.println("这是一个参数的方法:str:"+str); } private void show(String str,int num){ System.out.println("这是两个参数的方法:str:"+str+",num:"+num); } }
package _18反射.d3; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @author Lx * @create 2024-03-20 15:45 */ public class getMethodTest { public static void main(String[] args) { test1(); test2(); test3(); test4(); test5(); } //调公共无参方法 public static void test1(){ try { //1、获取JVM中的class Class c=Student.class; //2、用class获取公共方法 Method m=c.getMethod("show"); //3、调对象中的方法 Student stu=new Student(); m.invoke(stu); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } //调公共有参方法 public static void test2(){ try { //1、获取JVM中的class Class c=Student.class; //2、获取类中带参数的公共方法 Method m=c.getMethod("show",String.class); //3、获取对象中的方法 Student stu=new Student(); m.invoke(stu,"张三丰"); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } //调私有化有参方法 public static void test3(){ try { //1、获取JVM中的class Class c=Student.class; //2、获取类中的私有化带参方法 Method m=c.getDeclaredMethod("show",String.class,int.class); //3、获取对象中的方法 Student stu=new Student(); m.setAccessible(true);//获得访问权限 m.invoke(stu,"李四",50); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } //调空构造方法 public static void test4(){ try { //1、获取class Class c=Student.class; //2、获取class中的构造方法 Constructor con=c.getConstructor(); //3、把获取到的构造方法进行实例化,等号右边就相当于是new构造方法 //Student stu=new Student(); Student stu= (Student) con.newInstance(); stu.show(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } //调有参构造方法 public static void test5(){ try { //1、获取class Class c=Student.class; //2、获取class中的构造方法 Constructor con=c.getConstructor(String.class,int.class,String.class); //3、把获取到的构造方法进行实例化,等号右边就相当于是new构造方法 //Student stu=new Student(); Student stu= (Student) con.newInstance("张五",20,"四川"); stu.show(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }