剑指Offer(JVM)——反射(Reflect)

news/2024/5/19 3:02:04 标签: 反射, jvm

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

下面写一个反射相关的例子,来体现这个性质:

我们首先创建一个方法,然后在这个方法里面,设计两个有参的方法,一个是public修饰的,一个是private修饰的。

public class Robot {

    private String name;
    public void sayHi(String helloSentence) {
        System.out.println(helloSentence + "" + name);
    }

    private String throwHello(String tag) {
        return "hello" + "" + tag;
    }

}

现在倘若我们,创建一个新的class,将可以直接调用到sayHi方法,因为这个方法被public修饰,但是我们肯定无法调用到throwHello方法,因为是私有的,请看下图:

在这里插入图片描述

但是现在,我们将通过反射的方法,将私有的方法调用:

public class ReflectSample {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class rc = Class.forName("reflect.Robot");
        //参数是我们要反射的类的相对路径,通过参数,来获取到类
        
        Robot robot = (Robot) rc.newInstance();
        //利用newInstance,我们可以获得到这个类的一个实例
        
        System.out.println("Class name is" + rc.getName());
        //获取到实例,自然就能得到类名了
        
        robot.sayHi("Bob");
        //这时候,我们可以很自然的调用public修饰的方法
        
        Method getHello = rc.getDeclaredMethod("throwHello", String.class);
        //通过类名和接收的参数或得到这个类的某个任意的方法
        
        getHello.setAccessible(true);
        //因为我们要获取到的方法是私有的,所以需要设置setAccessible
        
        Object bob = getHello.invoke(robot, "Bob");
        //获取到方法后,使用invoke进行手动填写参数,然后会通过刚刚Method创建的实例自动调用对应的方法
        
        System.out.println(bob);

    }
}

上面编写的方法中,核心的反射的api是getDeclaredMethod,我们可以通过这个方法获取到任意的方法,不管是不是私有的,如果这个方法是public,我们就可以直接用getMethod来获取,这其实都好说,就是换一个api,但是如果我们想获取到这个方法内部的参数,该怎么做呢?

可以参考如下一整套的代码;

在这里插入图片描述


http://www.niftyadmin.cn/n/784273.html

相关文章

字符串在内存中的存储方式

字符串在内存中的存储方式 连续的空间,整个数组的大小是元素个数*元素类型大小 整形数组; int a[3]{1,2,3}; // 连续的空间,整个数组的大小是元素个数*元素类型大小printf("a数组的大小是;%d\n",sizeof(a));printf(&…

剑指Offer(JVM)——java类加载机制ClassLoader

这篇文章,我们主要来说说类从编译到执行的过程,假设我们有一个普普通通的类,名字叫做Robot.java 从我们编译这个类,到执行的这一段时间里,Robot一共执行了以下几个阶段: 编译器将Robot.java源文件编译为R…

sizeof和strlen在字符串计算中的区别

sizeof和strlen在字符串计算中的区别 int main() {int a[] {1,2,3};printf("数组a的元素个数;%d\n",sizeof(a)/sizeof(a[0]));char a2[] "hello";printf("数组a的元素个数;%d\n",sizeof(a2)/sizeof(a2[0]));printf(&qu…

剑指Offer(JVM)——ClassLoader的双亲委派机制

从之前的文章我们体会到,不同的类加载器对于类和路径的加载方式是有所不同的,并且各自负责各自的区块,使得逻辑更加的明确,但是这相互的协调工作,如果我们没有一定的方法,就会造成一定的问题,于…

字符串操作常用函数一

字符串操作常用函数一 知识点 puts 和 printf // puts API 函数char *str "老K 嵌入式";puts(str); //puts会自动加一个 \n 换行printf("%s\n",str); // puts 和 printf 作用基本一样运行结果 puts 和 printf 作用基本一样 注意;puts会自动加…

剑指Offer(JVM)——loadClass和forName的区别

在讲这两个方法之前,我先说一下,类的加载方式。 一个类被加载出来,是有两种方式的,分为隐式加载和显式加载: 隐式加载:new 显式加载:loadClass,forName等 隐式加载就不多说明了&…

字符串操作常用函数二

字符串操作常用函数二 知识点 1. 拷贝复制 strcpy stmcpy 格式;char strcpy(char dest,const char *src); char strdest[128] {\0};char *strsrc "老K,嵌入式";strcpy(strdest,strsrc);printf("复制字符串完毕,%s\n"…

剑指Offer(JVM)——Java内存模型解析

在开始讲java内存模型之前,首先我们先来了解一下关于内存方面的介绍: 在我们的程序执行中,需要不断的根据逻辑地址和物理地址之间进行映射,找到指令具体执行的位置。 Java程序运行在虚拟机之上,运行的时候也是需要内存…