RTTI与反射的区别和联系

本文深入探讨了Java反射机制的工作原理及应用场景,解释了为何需要反射,以及如何利用反射操作类和对象。通过实例展示了如何在运行时动态获取类信息并调用其方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为什么会有反射?

假如你在程序运行过程中,从磁盘上或者从网络上读取接收了一串代表一个类的字节,既然这个类在你的程序被编译很久之后才出现,那么你怎样使用这样的类呢?

 

解决:Class类和java.lang.reflect类库一起对反射的概念进行了支持。

 

下面讲的Class类将不仅仅局限在反射这个概念上:

Class类:

每个类和接口都有且仅有一个Class类型的对象,它由JVM自行创建,并且仅加载一次。每个类每个对象的创建都依赖于该类的Class类型对象。

如何获得一个类的Class对象?分为两种情况:

一:如果该类在编译前就已知。也就是该类在classPath路径下。这就是RTTI。

1)Class c = 类名.Class

 

2)Class c = Class.forName(String className)

 

二:如果该类编译器未知,也就是在程序运行时才知道的。这就是反射

 

1)Class c = Class.forName(String arg[0])

 

java.lang.reflect类库:

改类库中的Field类提供获取该不确定类中的字段的api

Class<?> c = Class.forNmae(Stringarg[0]);

Field[] fields = c.getFields();

该类库中的Method类提供获取该不确定类中的方法的api

Method[] methods = c.get Methods()

该类库中的Constructor类提供获取该不确定类中的构造器的api

Constructor []constructor= c.getConstructors()

注:想了解更多实用api请自行search for jdk文档

 

我们现在再来想为什么要有反射?

我们看我们遇到的问题是什么?在编译时编译器不知道某个特定类的信息,本质是编译时无法获得并打开特定类的.class文件,而是在程序运行起来时jvm才拥有该特定类的.class文件。那么,如何使用这样的文件呢?于是“反射”这个概念应运而生---提供在运行时操作.class文件的统一API。

 

所以,我们要认识到反射机制并没有什么神奇之处。反射与RTTI的本质区别只是检查一个类的.class文件的时机不同:

反射:.class 文件是在编译时不可获得的,所以在运行时打开和检查未知类的.class文件从而变已知。

RTTI:  .class 文件是在编译时打开和检查。



public static void main(String[] args) throws NoSuchMethodException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, MalformedURLException {
        //class.forName()
        Class c1 =  Class.forName("RTTI.model.PersonXYZ");
        Method[] m = c1.getMethods();
        for(int i=0;i<m.length;i++){
            System.out.println(m[i].getName());
        }
        
        System.out.println(c1.getName());
        
        Method ms = c1.getMethod("say",String.class);
        ms.invoke(c1.newInstance(),"10");
        
        //类字面常量
        Class c2 =  PersonXYZ.class;
        PersonXYZ p2 = (PersonXYZ)c2.newInstance();
        p2.say("12");
        
        //加载外部的class
        URLClassLoader  classLoader = new URLClassLoader(new URL[] { new URL("file:F:\\") });
        Class myClass = (Class)classLoader.loadClass("aa");
        Method myt = myClass.getMethod("say");
        myt.invoke(myClass.newInstance());
        
        
        
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值