浅析Java RTTI 和 反射的概念

简介: 一、概念: RTTI(Run-Time Type Identification,运行时类型识别)的含义就是在运行时识别一个对象的类型,其对应的类是Class对象,怎么理解这个Class对象呢?如果说类是所有对象方法、属性的集合,那就可以把这个Class对象理解成是所有class的集合,然后利用这个Class对象动态的解析出相关类,并可以获得其构造器和方法等,甚至实例化这个类的对象。

一、概念: RTTI(Run-Time Type Identification,运行时类型识别)的含义就是在运行时识别一个对象的类型,其对应的类是Class对象,怎么理解这个Class对象呢?如果说类是所有对象方法、属性的集合,那就可以把这个Class对象理解成是所有class的集合,然后利用这个Class对象动态的解析出相关类,并可以获得其构造器和方法等,甚至实例化这个类的对象。开始文章前,先提重要的一点:无论是RTTI还是反射,其本质都是一样的,都是去动态的获取类的信息,他们唯一的区别仅是:

  • RTTI 在编译期知道要解析的类型。
  • 反射 在运行期知道要解析的类型。

 

二、RTTI

有以下两种方式可以获取到Class对象:

    public static void main(String[] args)
    {
        try {
            //第一种方式
            Class rtti = Class.forName("com.jomoo.test.rtti.RTTI");
            //第二种方式
            Class type=RTTI.class;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

 可以看到,采用RTTI的方式必须在写程序的时候就知道了类的名字,才能获取到Class对象对这个类的引用,并利用这个引用,得到大量关于这个类的信息,包括接口,父类,方法,静态成员,甚至是像newInstance()方法这样的一个实现“虚拟构造器”的一种方式。

RTTI r =(RTTI)rtti.newInstance();//newInstance的类必须要有一个缺省构造器

         另外需要提一个经常用到 instanceof 该关键字的调用其实就是使用了Class对象,并且返回一个布尔值。

            Object o = rtti.newInstance();
            if (o instanceof RTTI){
                System.out.println(true);//这里需要注意的是,如果 o 是 RTTI的子类的话,返回的也会true;
            }

 

三、反射

Java中有时候在编译器为程序生成代码很久之后才会出现要处理的那个类,那么这个时候怎么才能处理这个类呢,即在编译的时候根本无法获知这个对象所属的类。答案就是利用Java的反射机制。废话不多说,看完下面这个代码你就很清楚的明白 RTTI 和 反射的区别在哪里了。

public class RTTI
{
    private  static final String usage="usage";
    private static Pattern pattern=Pattern.compile("\\w+\\.");

    public static void main(String[] args)
    {
        if (args.length<1){
            System.out.println(usage);
            System.exit(0);
        }
        int lines=0;
        try {
            Class c = Class.forName(args[0]);//看这里类的名字在编译的时候是无法得知的,只有在运行的时候动态传进去
            Method[] method = c.getMethods();
            Constructor[] constructors = c.getConstructors();
            if (args.length==1){
                for (int i=0;i<method.length;i++){
                    System.out.println(pattern.matcher(method[i].toString()).replaceAll(""));
                }
                for (int i=0;i<constructors.length;i++){
                    System.out.println(pattern.matcher(constructors[i].toString()).replaceAll(""));
                }
                lines=method.length+constructors.length;
            }else {
                for (int i=0;i<method.length;i++){
                    if (method[i].toString().indexOf(args[1])!=-1){
                        System.out.println(pattern.matcher(method[i].toString()).replaceAll(""));
                    }
                    lines++;
                }
                for (int i=0;i<constructors.length;i++){
                    if (constructors[i].toString().indexOf(args[1])!=-1){
                        System.out.println(pattern.matcher(constructors[i].toString()).replaceAll(""));
                    }
                    lines++;
                }
            }
        } catch (ClassNotFoundException e) {
            System.out.println("NO!!!!");
        }
    }
}

 如何在main方法中带入参数可以参考这篇博客我用原生的 javac -encoding UTF-8 RTTI.java 和 java RTTI com.jomoo.test.seven.ActionCharacter来运行 竟然报错了:Error: Could not find or load main class RTTI,我的JDK有毒!无奈借助了强大的IDE工具:

 

四、总结

其实RTTI的概念是在《Thinking in Java》中提到的,才引来这么多人的讨论,原生的Java中并没有这个概念的说法。所以勒,我们根本不必纠结是RTTI还是反射,他们无论用法还是本质都是一样的,都是为了实现一样的目的——动态的获取类的信息,我们应该把重点放在使用上,而不要过多在纠结在差异上。

目录
相关文章
|
2月前
|
缓存 Java 开发者
Java字面量详解:概念、分类与使用实例
本文介绍了Java字面量的概念、分类及应用。
64 11
|
2月前
|
Java 数据安全/隐私保护
Java的基础概念(二)
本文介绍了Java编程语言中的运算符和表达式,涵盖算术运算符、赋值运算符、关系运算符、逻辑运算符、三元运算符等。重点讲解了算术运算符的使用,如加减乘除取余,并强调了整数除法和取余的特殊性。同时,详细说明了隐式转换与强制转换的概念及应用场景,以及字符串和字符的拼接规则。通过多个案例演示了不同运算符的实际应用,包括数值拆分、自增自减、三元表达式的使用等。最后简要提及了运算符的优先级,指出小括号具有最高优先级。
|
3月前
|
Java 数据库连接 Spring
反射-----浅解析(Java)
在java中,我们可以通过反射机制,知道任何一个类的成员变量(成员属性)和成员方法,也可以堆任何一个对象,调用这个对象的任何属性和方法,更进一步我们还可以修改部分信息和。
|
3月前
|
存储 Java 程序员
Java的基础概念一
### Java编程基础简介 #### 一、注释 注释用于解释代码,不会参与编译和运行。Java支持三种注释: - **单行注释**:以 `//` 开头。 - **多行注释**:以 `/* ... */` 包围。 - **文档注释**:通常用于生成开发文档。 #### 二、关键字 关键字是被Java赋予特定含义的英文单词,全部小写,且在代码编辑器中有特殊颜色标记。常用的如 `class` 表示定义一个类。
Java的基础概念一
|
4月前
|
监控 Java
Java基础——反射
本文介绍了Java反射机制的基本概念和使用方法,包括`Class`类的使用、动态加载类、获取方法和成员变量信息、方法反射操作、以及通过反射了解集合泛型的本质。同时,文章还探讨了动态代理的概念及其应用,通过实例展示了如何利用动态代理实现面向切面编程(AOP),例如为方法执行添加性能监控。
|
4月前
|
Java
Java的反射
Java的反射。
54 2
|
4月前
|
算法 Java 数据库连接
Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性
本文详细介绍了Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性。连接池通过复用数据库连接,显著提升了应用的性能和稳定性。文章还展示了使用HikariCP连接池的示例代码,帮助读者更好地理解和应用这一技术。
110 1
|
5月前
|
存储 Java
[Java]反射
本文详细介绍了Java反射机制的基本概念、使用方法及其注意事项。首先解释了反射的定义和类加载过程,接着通过具体示例展示了如何使用反射获取和操作类的构造方法、方法和变量。文章还讨论了反射在类加载、内部类、父类成员访问等方面的特殊行为,并提供了通过反射跳过泛型检查的示例。最后,简要介绍了字面量和符号引用的概念。全文旨在帮助读者深入理解反射机制及其应用场景。
79 0
[Java]反射
|
5月前
|
IDE Java 编译器
java的反射与注解
java的反射与注解
43 0
|
5月前
|
安全 Java 测试技术
🌟Java零基础-反射:从入门到精通
【10月更文挑战第4天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
71 2

热门文章

最新文章