类型信息

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类型信息相关的知识,希望对你有一定的参考价值。

RTTI 运行时类型信息

在Java中.所有的类型转换都是在运行时进行正确性检查的,这也是RTTI的名字含义,在运行时识别一个对象的类型.

而RTTI的另一个重要作用在于,在多态的情况下,保证一个向上转型后的泛化引用能调用真正的对象类型的方法.

Class对象

Java使用Class对象来执行其RTTI.类是程序的一部分,每个类都有一个Class对象,也就是每编写一个新的类,都会产生一个Class对象,被保存在同名的.class文件中.JVM使用类加载器生成这个类的对象.Class引用总是指向某个Class对象,它可以制造类的实例,并包含个作用于这些实例的所有方法代码和该类的静态成员.

获取class对象的方法

  • Class.forName()方法,给该方法传入一个类的全限定名,可以获得该类class对象的引用.
  • 已有对象的情况下,使用object.getClass()方法
  • 类字面常量,使用类名.class,这样做更加安全也更简单.可以在编译期受到检查,也不会调用Class.forName()方法更加的高效.

使用.class获得class对象的引用时并不会自动初始化该类

使用类的准备工作分为三步:

  1. 加载:查找字节码,从字节码中创建一个Class对象
  2. 链接: 验证类中的字节码, 为静态域分配存储.必需情况也会解析这个类创建的对于其他类的引用
  3. 初始化: 对超类执行静态初始化器和静态初始化块.

初始化只有在调用静态方法或者非常数静态域的首次引用时执行.

泛化的Class引用

使用泛型语法可以限定Class引用指向的类型,而且可以使编译器提供编译时检查
Class

新的转型语法

可以使用class引用.cast()方法接受一个参数对象,将其转换为class引用的类型,但是相比普通的使用小括号类型转换多做了额外的工作,并不使用.

类型转换前先做检查

普通的类型转换如(int)c这样由RTTI确保类型转换的正确性

RTTI还有第三种形式,就是转换前调用instanceof参数,它将检测对象是否处于目标类型的实例,并返回一个boolean值,这将给编译器提供更多的信息,否则将会报出ClassCastException异常

instanceof和使用Class对象的区别

instanceof会考虑派生类的问题,如果时派生类也会返回true,但是直接判断Class对象不会考虑继承,他只会考虑确切的类型是否相等

反射

RTTI是在编译时打开和检查.class文件,而对于反射来讲,.class文件是编译时不可获取的,因此需要在运行时打开和检查.class文件

类方法提取器

Class对象的getMethods()方法和getConstructors()方法分别返回代表method对象的数组和constructor对象的数组

动态代理

Java的动态代理可以动态的创建代理饼动态的处理对所代理方法的调用.

package com.renluxiang.neibulei;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class SimpleDynamicProxy {
    public static void main(String[] args) {
        Real r = new Real();
        Interface proxy = (Interface) Proxy.newProxyInstance(Real.class.getClassLoader(),new Class[]{Interface.class},
                new handler(r));
        proxy.doSomething();
    }
}

class handler implements InvocationHandler{
    private Object proxied;

    public handler(Object proxied){
        this.proxied = proxied;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(proxied,args);
    }
}

interface Interface{
    public void doSomething();
}

class Real implements Interface{

    @Override
    public void doSomething() {
        System.out.println("1");
    }
}




以上是关于类型信息的主要内容,如果未能解决你的问题,请参考以下文章

vbscript 各种自定义代码片段 - 有关详细信息,请参阅注释

一个具有两种显示类型的片段[关闭]

(转) Java中的负数及基本类型的转型详解

GMSMarker 信息窗口内容(片段)未更新

片段“F1”不能在这里传播,因为“节点”类型的对象永远不能是“商店”类型

错误记录Flutter 混合开发获取 BinaryMessenger 报错 ( FlutterActivityAndFragmentDelegate.getFlutterEngine() )(代码片段