剑指Offer(JVM)——反射

Java反射机制是在运行状态中,对于任意一个类都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。

接下来举一个反射的例子:
创建一个实体类,包含两个有参方法,一个是public修饰一个是private修饰。

public class Person {
    
    private String name;
    
    public void satHello(String sentence){
        System.out.println(sentence + " " + name);
    }
    
    private String hello(String flag){
        return "Hello" + " " + flag;
    }
}

在一个新的类中是可以调用到sayHello方法的,但是无法调用到hello方法,因为hello方法时私有的。

通过反射是可以调用到私有方法的:

public class PersonReflect {
    public static void main(String[] args) throws ClassNotFoundException, 
            IllegalAccessException, 
            InstantiationException, 
            NoSuchMethodException, 
            InvocationTargetException {
        //参数是累的相对路径,通过参数获取到类
        Class dp = Class.forName("daily.Person");

        //利用newInstance获得这个类的实例
        Person person = (Person) dp.newInstance();

        System.out.println("Class name is : " + dp.getName());

        //可以调用的public修饰的方法
        person.sayHello("LJY");

        //通过类名和接收到的参数得到这个类任意的某个方法
        Method sayHello = dp.getDeclaredMethod("hello", String.class);

        //要调用的方法是私有的,需要将setAccessible设置为true
        sayHello.setAccessible(true);

        //使用invoke填写参数,通过Method创建的实例自动调用对应的方法
        Object ljy = sayHello.invoke(person, "ljy");

        System.out.println(ljy);
    }
}

上面所示实例中,反射的API是getDeclaredMethod,可以通过这个API获取到任意的方法不管是私有的还是共有的。如果是public修饰的方法,可以直接使用getMethod,但是如果要是想要获取到这个方法内部的参数该如何操作???

完整的代码参考如下:

public class PersonReflect {
    public static void main(String[] args) throws ClassNotFoundException,
            IllegalAccessException,
            InstantiationException,
            NoSuchMethodException,
            InvocationTargetException,
            NoSuchFieldException {
        //参数是累的相对路径,通过参数获取到类
        Class dp = Class.forName("daily.Person");

        //利用newInstance获得这个类的实例
        Person person = (Person) dp.newInstance();

        System.out.println("Class name is : " + dp.getName());

        //可以调用的public修饰的方法
        person.sayHello("LJY");

        //通过类名和接收到的参数得到这个类任意的某个方法
        Method hello = dp.getDeclaredMethod("hello", String.class);

        //要调用的方法是私有的,需要用setAccessible设置为true
        hello.setAccessible(true);

        //使用invoke填写参数,通过Method创建的实例自动调用对应的方法
        hello.invoke(person, "ljy");

        Method sayHello = dp.getMethod("sayHello", String.class);
        sayHello.invoke(person, "Hello");

        //获取Person实体类中的属性
        Field name = dp.getDeclaredField("name");

        //属性是私用的需要用setAccessible设置为true
        name.setAccessible(true);

        name.set(person, "LJYLJY");
        sayHello.invoke(person, "Hello");

    }
}
发布了242 篇原创文章 · 获赞 23 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44240370/article/details/104052914