首页 > 其他分享 >Type information 反射信息 Type指一个对象的种类,某种自定义的class,某个interface或string等,都是type的一种。

Type information 反射信息 Type指一个对象的种类,某种自定义的class,某个interface或string等,都是type的一种。

时间:2024-02-19 19:34:38浏览次数:25  
标签:information 自定义 对象 type Class 实例 Type class

Type information 反射信息 Type指一个对象的种类,某种自定义的class,某个interface或string等,都是type的一种。

 (本文参考了 Thinking in java中的type information这章)


  • 什么是Type information

Type指一个对象的种类,某种自定义的class,某个interface或string等,都是type的一种。

而type information即是指关于这个对象的信息。例如后面会提到,Class.forName()将返回class的名称,就是所谓的type information之一。


在两个阶段可以得知一个对象的类型:

1, 在编译阶段就已经可以得到所有的type。 例如,定义的一个String对象,在编译阶段就可得知该对象是一个String。

2, 另外一种反射机制,它允许你在运行时发现和使用对象的类型信息,即type information.


而RTTI(runtime type information)就指在运行时,获得type information的机制。

大家熟知的多态,就是RTTI的一种典型情况。而在后面的内容中我们慢慢的就能知道,可以利用runtime type information做些什么有趣的事情。

现阶段我们只需要知道利用RTTI我们可以build more powerful program(现在听起来很虚是吧~~)


  • RTTI的意义:

一个简单的例子,一个基类 Shape和它的三个子类:三角形,圆形和方形。

public class Shapes {
public static void main(String[] args) {
List<Shape> shapeList = Arrays.asList(
new Circle(), new Square(), new Triangle()
);
for(Shape shape : shapeList)
shape.draw();
}
}

从上例可以看出,这些子类的实例被放入了List<Shape>中。此时the upcast occurs when the shape is placed into the List<Shape>. During the upcast to Shape, the fact that the objects are specific types of Shape is lost. To the array, they are just Shapes.

当你从List<Shape>中将每个形状取出并draw()时,就使用了典型的RTTI。因为所有的对象从List中取出时,这些对象被自动从基类shape转换成了具体的形状,并执行特定形状的draw()。而这正是RTTI的意义所在:在运行时,一个对象的type被确认。这是实现多态的基础。


  • type information 在runtime是如何被表示的。

要理解RTTI在java中是如何工作的,你必须先知道type information在run time是如何被表示的。

我们知道一个类有两种成员变量:用static修饰的变量,被称为类变量或静态变量。静态变量是属于类本身的。没有被static修饰的变量是实例变量,是属于一个具体的类实例的。

因此我们可以得出这样一个结论:一个类在JVM中应该被表现成两部分:类本身,以及类的实例。

事实也是如此:在JVM中,一个类有两个部分:

1,表现这个类本身的对象Class

2,以及这个类的诸多实例对象。


在java中,有一个特殊的类,叫Class类。在一个类第一次被使用时(我们在后面解释什么叫“被使用时”),JVM中产生了两个东西:首先创建一个代表类本身的对象,这个对象是Class类的实例。接着创建类的实例。

而这个Class类的实例,就存储了这个类的type infomation。

注意在JVM中,一个类只会有一个Class类的实例与之对应,但是可以有任意多个类的实例。也就是说,你可以实例化一个类任意多次,但是在JVM中对应的Class类的实例只会被创建一个。

再换句话说:一个类的任意多个实例是共享一个Class类实例的。这非常合理,因为一个类的实例再多,但是属于类本身的信息有一份就够了。


1,Class对象是怎么产生的

 That is, each time you write and compile a new class, a single Class object is also created (and stored, appropriately enough, in an identically named .class file).

.class文件(即jar文件)在运行时,会被JVM中的一个重要组件:class loader装载并创建出对应的Class object。


2,Class object如何工作

所有的类都是在第一次被调用时,动态的被load到JVM的. 所谓的“第一次被调用”,就是类中的静态成员被调用。而构造函数也是类的静态方法,因此load在以下情况发生:

1,类的static成员变量或方法被调用时。

2,或new一个类时。

因此,一个java程序并不是在运行前被完全load到JVM中,而且分多次,一小段一小段的load。这导致了和c++这种statically loaded 语言在行为上的不同。

Once the Class object for that type is in memory, it is used to create all objects of that type。

上句意思是:一旦一个类的Class object在内存中了,它就会被用来创建所有该类的对象。非常合理,因为如果一个类对应的Class对象已经在JVM存在了,且我们仅需要一份,那么就不需要再创建了。


3,如何使用Class object。

要使用type information,我们必须先得到一个Class类实例的引用,然后使用这个类提供的方法,得到我们想要的information:

Anytime you want to use type information at run time, you must first get a reference to the appropriate Class object.


Class.forName()可以返回一个类对应的Class对象:Returns the Class object associated with the class or interface with the given string name.

例如,class.forName("TestClass"); 就返回了TestClass这个类对应的那个Class类实例,也就是代表了TestClass这个类的type information的那个对象。

还有一种方法就是使用Class literals:

类名+.class就是class literral。

我常常在代码中看到的,log4j就会使用:

private final static Logger LOGGER = Logger.getLogger(ClassName.class);

但是使用.class并不会导致立即实例化对应的class。


得到了引用后,我们想获得任何关于类的type information就非常简单了:其实就是使用Class这个类提供的方法。

打开java.lang.Class的java doc,浏览一遍这个类提供的所有方法,心里就有数了。下面以最常用的几个方法举例。

getName()得到当前的这个类的名字。

其他有用的方法:

getClass():继承于Object的Returns the runtime class of an object.  其实返回的就是一个Class的实例。

Class.islnstance( ): Determines if the specified Object is assignment-compatible with the object represented by thisClass.

instanceof。

getClassLoader()可以知道这个类是被哪个class loader load到JVM的。




原文链接:https://blog.csdn.net/OnlyQi/article/details/6706595

标签:information,自定义,对象,type,Class,实例,Type,class
From: https://www.cnblogs.com/sunny3158/p/18021788

相关文章

  • Flink 使用之 TypeInformation 由于泛型类型在运行时会被JVM擦除,所以要指定类型
    Flink使用之TypeInformation由于泛型类型在运行时会被JVM擦除,所以要指定类型Flink使用介绍相关文档目录Flink使用介绍相关文档目录背景本篇从近期遇到的StreamJavaAPI问题,引出TypeInformation的使用。Exceptioninthread"main"org.apache.flink.api.common.functi......
  • 将控件提升为自定义的控件
    一、自定义控件的类型自定义拖动的设计文件(.h、.cpp、.ui)和自定义的自绘文件(.h、.cpp)二、打开提升窗口三、设置自定义类路径四、注意事项1.若自定义控件与提升窗口不在同一路径,且置于pri文件中。则会导致自定义的控件编译报错。"noruletomaketargetxxx......
  • HTML <!DOCTYPE>标记
    原文链接:https://blog.csdn.net/wuxiaopengnihao1/article/details/126521900描述HTML <!DOCTYPE>标记一般放在HTML文档中的第一行。它告诉浏览器要编写文档的HTML版本,以便浏览器知道预期的内容。此标记通常也称为<!DOCTYPE>元素。句法<!DOCTYPE>标记的语法在所使用的HTML或XHTML......
  • [Go] Get used to return (*SomeType, error) as function return type
    packagemainimport( "fmt" "log" "strconv" "strings")typePointstruct{ xint yint}typeLinestruct{ p1*Point p2*Point}funcgetInput()string{return`0,9->5,98,0->0,89,4->......
  • [win_os] chrome浏览器 -- 添加自定义搜索引擎并将其设置为默认搜索引擎(转载裁切
    [win_os]  chrome浏览器 -- 添加自定义搜索引擎并将其设置为默认搜索引擎(转载裁切)    一、必要说明  1、添加搜索引擎【bing】:https://global.bing.com/search?q=%s  2、重点说明【红色部分一点都不能错】:https://global.bing.com/sea......
  • 微信自定义关键词,自动回复,微信公众号文章采集,开发已测试,欢迎大家来测试使用!
    本文主要是通过获取本地的句柄然后用来截取微信的消息,所以可以有效做到 零封号 零丢包 零失误  !!!经测试,可以自定义关键词和回复语(一行一个)可无限添加关键词和对应的回复语!回复时间基本在1秒以内,可以做到检测到关键词存在时即时回复的功能,可以获取到微信公众号文章等信......
  • 这款完全自定义配置的浏览器起始页插件值得你收藏!
    大家好,我是Java陈序员。浏览器是我们上网冲浪的必备工具,每次打开浏览器默认都是先看到起始页。有的浏览器起始页十分简洁美观,而有的则是充满了各种网址导航和广告。今天,給大家介绍一个浏览器起始页配置插件,支持自定义配置。关注微信公众号:【Java陈序员】,获取开源项目分享、A......
  • typescript修改target导致模块找不到
    编译ts代码时,发现一个包只支持es6及更高的版本,无奈修改编译选项target,从es5修改为es6,发现原来导入包的地方报错,提示notfound。tsconfig.json{"files":["src/main.ts"],"compilerOptions":{"noImplicitAny":true,"target":......
  • 在script标签写export为什么会抛错|type module import ES5 ES6 预处理 指令序言 JavaS
    今天我们进入到语法部分的学习。在讲解具体的语法结构之前,这一堂课我首先要给你介绍一下JavaScript语法的一些基本规则。脚本和模块首先,JavaScript有两种源文件,一种叫做脚本,一种叫做模块。这个区分是在ES6引入了模块机制开始的,在ES5和之前的版本中,就只有一种源文件类型(就......
  • typecho 迁移服务器
     一、遇到的问题1.由于服务器到期,域名也到期,之前写的文章还有很多有用的就续费了一个月的腾讯云。使用之前的镜像制作系统,制作成功后,开启NGINX服务,开放端口,访问网站发现资源地址还是之前的域名地址。 二、解决过程1.不知道在哪里修改就把数据库导出来,重新搭建typecho环境,发......