【JAVA】反射

1.什么是反射

通过类的全类名就能把这个类的所有方法和变量的信息(方法名,变量名,方法,修饰符,类型,方法参数等等所有信息)找出来。如果明确知道这个类里的某个方法名+参数个数 类型,还能通过传递参数来运行那个类里的那个方法,这就是反射。反射的具体方法不多说。这里只说三种获得类类型的方式:

  • 通过类名.class获得,执行静态块、不执行动态构造块,动态构造块在newInstance的时候执行
  • 通过对象名.getClass()获得 (需要获得实例对象),实例对象的时候执行静态块和动态构造块
  • 通过Class.forName(“类全名”)获得,执行静态块、不执行动态构造块,动态构造块在newInstance的时候执行

2.反射的原理

3.反射使用时的技巧

⑴invoke方法可以传入强转后传object[]
public class Test {

    public static void main(String[] args) throws Exception {
        Dog dog = new Dog();
        dog.setLength(123);
        dog.setName("蔡丸子");
        Object object = (Object) dog;
        // 通过下面的方式也可以.
        // Object object = JSONObject.parseObject("{\"length\":123,\"name\":\"黑豆\"}",Dog.class); object.class是不行的.

        Man man = new Man();
        man.setAge(23);
        man.setName("蔡彬");
        Object object1 = (Object) man;

        // 这里的objects里面必须是强转后的,否则调用方法的时候报类型不匹配.
        Object[] objects = new Object[]{
                object, object1
        };

        Class<?>[] a = new Class<?>[]{
                Class.forName("testswitch.Dog"),
                Class.forName("testswitch.Man")
        };
        Class<?> clazz = Class.forName("testswitch.Test");
        Method method = clazz.getDeclaredMethod("test",a);
        method.invoke(clazz.newInstance(),objects);
    }

    public void test(Dog dog, Man man) {
        System.out.println(dog.getLength());
        System.out.println(man.getAge());
    }

    public void test1() {
        System.out.println("123");
    }
}

输出:

123
23
⑵调用无参方法传null或者空集合都可以
    public static void main(String[] args) throws Exception {
        Object[] objects = new Object[]{
        };
        Class<?>[] a = new Class<?>[]{
        };
        Class<?> clazz = Class.forName("testswitch.Test");
        // a是null也可以.
        Method method = clazz.getDeclaredMethod("test1", a);
        // objects是null也可以.
        method.invoke(clazz.newInstance(), objects);
    }

    public void test1() {
        System.out.println("123");
    }

输出:

123
⑶反射中包含有可变的参数.
public class TestInvoke {

    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("testswitch.TestInvoke");
        Method method = clazz.getDeclaredMethod("getYear", String[].class);
        String[] in = new String[]{"123"};
        // 引用类型我们需要把这个数组实参先包装成一个Object对象或把实际参数作为一个Object一维数组的元素再传递.不传的话传一个new数组进去.
        method.invoke(clazz.newInstance(), (Object) in);
        method.invoke(clazz.newInstance(), new Object[]{in});
        // 基本类型不需要.
        Method method2 = clazz.getDeclaredMethod("getYear2", int[].class);
        int[] in2 = new int[]{123};
        method2.invoke(clazz.newInstance(),in2);

    }
    public int getYear(String... in) {
        System.out.println("123");
        return 666;
    }

    public int getYear2(int... in) {
        System.out.println("222");
        return 888;
    }
}

输出:

123
123
222
⑷反射方法中有集合
public class TestInvoke {

    public static void main(String[] args) throws Exception {
        Man man = new Man();
        man.setName("蔡彬");
        man.setAge(23);

        Dog dog1 = new Dog();
        dog1.setName("狗1");

        Dog dog2 = new Dog();
        dog2.setName("狗2");

        Class<?> c = Class.forName("testswitch.TestInvoke");

        Class<?> p1 = Class.forName("testswitch.Man");

        // 这里直接是List的全限定名.
        Class<?> p2 = Class.forName("java.util.List");

        Class<?>[] array = new Class[]{p1, p2};

        Method method = c.getDeclaredMethod("getYear", array);

        List<Dog> dogs = new ArrayList<>();

        dogs.add(dog1);
        dogs.add(dog2);


        Object[] manobjects = new Object[]{man, dogs};

        method.invoke(c.newInstance(), manobjects);
    }

    public void getYear(Man man, List<Dog> dogs) {
        for (int i = 0; i < dogs.size(); i++) {
          System.out.println(dogs.get(i).getName());
        }
    }
    
}
⑸反射获得基本类型数组,基本类型取不到
Class intArray = Class.forName("[I");
Class stringArrayClass = Class.forName("[Ljava.lang.String;");

我们不知道的可以这样打出来:

        long[] longs = new long[]{
                1,2,3
        };
        // [[J@555590] 就是[J
        System.out.println(Arrays.asList(longs));
⑹反射获取对象数组
Class stringArrayClass = Array.newInstance(Class.forName("testswitch.Dog"), 0).getClass();

Class stringArrayClass = Class.forName("[L" + "testswitch.Dog" + ";");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值