java中的反射
1、java中的反射:
首先要理解什么是Class类,反射就是通过获取Class对象之后的一系列操作。
1、对于每个类而言,JRE 都为其保留一个不变的 .Class 类型的对象。一个 Class 对象包含了特定某个类的有关信息。
2、Class 对象只能由系统建立对象。每个类的实例都会记得自己是由哪个 Class 实例所生成。
3、一个类在 JVM 中只会有一个Class实例。
2、获取Class对象的三种方式:
package com.example.demo.test; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Constructor; import java.util.Arrays; public class ReflectionTest2 { static class Test { } static class Person { public String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } } /** * 实例化Class类的方式有点特殊,有三种方式: 对象.getClass( )、 类.Class 、 Class.forName(“包名下的类”) * * Class<?> class 方法 * * 反射调用 */ public static void main(String[] args) throws Exception { //方式一: Test test = new Test(); Class<?> c1 = test.getClass(); System.out.println(c1); //方式二: //为了避免特殊性,这里不用Test类,而用java库中的String类 Class<String> c2 = String.class; System.out.println(c2); //方式三: //forName()方法会抛出异常 Class<?> c3 = null; try { c3 = Class.forName("com.example.demo.test.ReflectionTest2"); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.out.println(c3); //====================Class对象里面的属性=============================================== Class<?> c = null; try { c = Class.forName("java.lang.String"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Constructor<?>[] cons = c.getConstructors(); System.out.println("取得类的构造方法:" + Arrays.toString(cons)); Class<?>[] in = c.getInterfaces(); System.out.println("取得类所实现的接口:" + Arrays.toString(in)); Class<?> su = c.getSuperclass(); System.out.println("取得父类:" + su); Method[] methods = c.getMethods(); for (int i = 0; i < methods.length; i++) { //System.out.println("取得类的全部方法:" + methods[i]); } Field[] f = c.getDeclaredFields(); for (int i = 0; i < f.length; i++) { System.out.println("取得本类的全部属性:" + f[i]); } //=========================重设反射对象的值========================================== Person p = new Person("zhangsan",12); Class<?> aClass = p.getClass(); //获取公共属性的值 Field f1 = aClass.getField("name"); //get(p)表明要获取是哪个对象的值 String str = (String) f1.get(p); System.out.println("姓名:" + str); //获取私有属性的值 Field f2 = aClass.getDeclaredField("age"); //age是私有属性,所以要设置安全检查为true f2.setAccessible(true); int age = (int) f2.get(p); System.out.println("年龄:" + age); } }
3、反射方法使用:
package com.example.demo.test; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * @Author Tim * @Date 2021/2/4 11:29 */ class Person { private String name; public Person(String name) { this.name = name; } public String toString() { return "姓名: " + this.name; } public void print(int i) { System.out.println("我在写字: " + i); } public static void say(String str) { System.out.println("我在说话: " + str); } } public class ReflectionTest3 { //===================通过反射修改对象属性================================================ public static void main(String[] args) throws Exception { Person p = new Person("王二狗"); System.out.println("反射前对象===" + p); Class<?> c = p.getClass(); //定义要修改的属性 Field f = c.getDeclaredField("name"); f.setAccessible(true); //修改属性,传入要设置的对象和值 f.set(p, "张二蛋"); System.out.println("通过反射修改属性===" + p); //====================通过反射调用对象方法=============================================== //getMethod()方法需要传入方法名,和参数类型 Method m1 = c.getMethod("print", int.class); //invoke()表示调用的意思,需要传入对象和参数 m1.invoke(p, 10); Method m2 = c.getMethod("say", String.class); //这里的null表示不由对象调用,也就是静态方法 m2.invoke(null, "你妹"); } }
测试demo1:
package com.example.demo.test; import java.lang.reflect.Method; class FunClass { public String sayHello(String s) { return "hello!" + s; } } public class Test { public static void main(String[] args) throws Exception { Class<?> clz = Class.forName("com.example.demo.test.FunClass"); // Object obj = clz.newInstance(); //获取方法 Method m = obj.getClass().getMethod("sayHello", String.class); //调用方法 String result = (String)m.invoke(obj, "参数,李"); System.out.println(result); } }
学海无涯 代码作伴