类型信息
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对象的引用时并不会自动初始化该类
使用类的准备工作分为三步:
- 加载:查找字节码,从字节码中创建一个Class对象
- 链接: 验证类中的字节码, 为静态域分配存储.必需情况也会解析这个类创建的对于其他类的引用
- 初始化: 对超类执行静态初始化器和静态初始化块.
初始化只有在调用静态方法或者非常数静态域的首次引用时执行.
泛化的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 各种自定义代码片段 - 有关详细信息,请参阅注释
片段“F1”不能在这里传播,因为“节点”类型的对象永远不能是“商店”类型
错误记录Flutter 混合开发获取 BinaryMessenger 报错 ( FlutterActivityAndFragmentDelegate.getFlutterEngine() )(代码片段