Java类型信息
一、引言
最近在阅读《Java编程思想》,学习一下java类型信息,现在做一下总结。Java如何让我们在运行时识别对象和类的信息的。主要有两种方式:一种是传统的“RTTI”,它假定我们在编译时已经知道了所有的类型;另一种是“反射”机制,它允许我们在运行时发现和使用类的信息。
二、Class对象
要理解RTTI的工作原理,首先必须知道类型信息在运行时是如何表示的。这项工作是由称为Class对象的特殊对象完成的,它包含了与类有关的信息。事实上,Class对象就是用来创建类的所有“常规”对象的。Java使用Class对象来执行RTTI,即使你正在执行的是类似转型这样的操作。Class类还拥有大量使用RTTI的其它方式。
类是程序的一部分,每个类都有一个Class对象。换言之,每当编写并且编译一个新类,就会产生一个Class对象(更恰当的说,是被保存在一个同名.class文件中)。为了生成这个类的对象,运行这个程序的Java虚拟机(JVM)将使用被称为“类加载器”的子系统。
类加载器子系统实际上可以包含一条类加载器链,但是只有一个原生类加载器。它是JVM实现的一部分。原生类加载器加载的是所谓的可信类,它包括Java API类,它们通常是从本地盘加载的。在这条链中,通常不需要额外的类加载器,但是如果你有特殊需求(例如以某种特殊方式加载类,以支持Web服务器应用,或者在网络中下载类),那么你有一种方式可以挂接这个额外的类加载器。
所有的类都是在对其第一次使用时候,动态加载到JVM中的。当程序创建第一个对类的静态成员引用时,就会加载这个类。这个证明构造器也是类的静态方法,即使在构造器之前并没有使用static关键字。因此使用new 操作符创建的新的类对象也会被当做是对类的静态成员的引用。
三、Class对象的生成方式如下
1.Class.forName("类名字符串")
2.类名.class
3.实例对象.getClass()
四、为了使用类而做的准备工作实际包含三个步骤:
1.加载。 这是由类加载器执行的。该步骤将查找字节码(通常在classpath所指的路径中查找,但并非是必需的),并从这些字节码中创建一个Class对象。
2.链接。 在链接阶段将验证类中的字节码,为静态域分配存储空间,并且如果必需的话,将解析这个类创建对其他类的所有引用。
3.初始化。 如果该类具有超类,则对其超类初始化,执行静态初始化器和静态初始化块。初始化被延迟到了对静态方法(构造器隐式的是静态的)或者非常数静态域进行首次引用时才执行:
下面是一个初始化的例子
import java.util.Random;
class Initable{
static final int staticFinal = 47 ;
static final int staticFinal2 =
ClassInitialization.random.nextInt(1000);
static {
System.out.println("Initialzing Initable");
}
}
class Initable2{
static final int staticNonFinal = 147 ;
static{
System.out.println(" Initializing Initable2 ");
}
}
class Initable3{
static int staticNoFinal = 74 ;
static {
System.out.println("Initializing Initable3");
}
}
public class ClassInitialization {
public static Random random = new Random(47);
public static void main(String[] args) throws Exception{
Class initable = Initable.class ;
System.out.println("After creating Initable ref");
System.out.println(Initable.staticFinal);
System.out.println(Initable.staticFinal2);
System.out.println(Initable2.staticNonFinal);
Class initable3 = Class.forName("Initable3") ;
System.out.println("After creating Initable3 ref");
System.out.println(Initable3.staticNoFinal);
}
}
运行结果如下:
After creating Initable ref
47
Initialzing Initable
258
147
Initializing Initable3
After creating Initable3 ref
74
这个例子展示了:
1.初始化尽可能“惰性”。对initable引用的创建中可以看到, 仅使用.class语法来获得对类的引用不会发生初始化。但是,为了产生Class引用,Class.forName()立即就进行了初始化,就像在initable3引用创建中看到的。
2.如果一个static final 值是“编译期常量”,就像Initable.staticFinal那样,那么这个值不需要对Initable类进行初始化话就可以被读取。但是,如果只是将一个域设置为static 和final的,还不足以确保这种行为,例如,对Initable.staticFinal2的访问将强行进行类初始化,因为它不是一个编译期常量。
3.如果一个static域不是final的,那么在对它进行访问时,总是要求在它被读取之前,要先进行连接(为这个域分配存储空间)和初始化(初始化该存储空间),就像在对Initable.staticNonFinal的访问中看到的那样。
五、Class对象方法概述:
1.Class对象概述
(1)持有RTTI信息
(2)每个类都有一个Class对象,每当编译一个新类就产生一个Class对象。
(3) Class引用总是指向某个Class对象。Class引用表示的就是它所指向的对象的确切类型,而该对象便是Class类的一个对象。
2.forName()
(1) 获取Class对象的一个引用,但引用的类还没有加载(该类的第一个对象没有生成)就加载了这个类.
(2) 为了产生Class引用,forName()立即就进行了初始化。
3.Object-getClass() 获取Class对象的一个引用,返回表示该对象的实际类型的Class引用。
4.getName() 获取全限定的类名(包括包名),即类的完整名字。
5.getSimpleName() 获取类名(不包括包名)
6.getCanonicalName() 获取全限定的类名(包括包名)
7.isInterface() 判断Class对象是否是表示一个接口
8.getInterface() 返回Class对象,表示Class对象所引用的类所实现的所有接口。
9.getSupercalss() 返回Class对象,表示Class对象所引用的类所继承的直接基类。应用该方法可在运行时发现 一个对象完整的继承结构。
10.newInstance() 返回一个Oject对象,是实现“虚拟构造器”的一种途径。“虚拟构造器”:我不知道你的确切的 类型,但无论如何都要正确创建你自己。用该方法创建的类,必须带有默认的构造器。
11.cast() 接受一个对象为参数,并将其转型为Class引用的类型。该法一般是在无法使用普通转型的情况下使用。
12.getClassLoader() 返回该类的类加载器。
13.getComponentType() 返回表示数组组件类型的Class。
14.isArray() 判定此 Class 对象是否表示一个数组类。
15.泛化的Class引用
1)实现方法:使用通配符“?”。
2)Class<?>优于Class,即便他们是等价的。
3)Class<?>的好处是明确地告诉编译器你选择了非具体的类版本,而不是由于碰巧或者疏忽而使用了一个非具体的类引用。
4)创建一个范围:创建一个Class引用 ,使它被限定为某种类型<className>;或该类型的任何子类型,< ? extends superClass>;或者该类型的超类,< ? super super sunClassName>
Java类型信息的更多相关文章
- JAVA类型信息——反射机制
JAVA类型信息——反射机制 一.反射机制概述 1.反射机制:就是java语言在运行时拥有的一项自我观察的能力,java通过这种能力彻底了解程序自身的情况,并为下一步的动作做准备. 2.反射机制的功能 ...
- JAVA类型信息——Class对象
JAVA类型信息——Class对象 一.RTTI概要 1.类型信息RTTI :即对象和类的信息,例如类的名字.继承的基类.实现的接口等. 2.类型信息的作用:程序员可以在程序运行时发现和使用类型信息. ...
- Java基础 -- 深入理解Java类型信息(Class对象)与反射机制
一 RTTI概念 认识Claa对象之前,先来了解一个概念,RTTI(Run-Time Type Identification)运行时类型识别,对于这个词一直是 C++ 中的概念,至于Java中出现RT ...
- JAVA类型信息——Class对象(转载)
JAVA类型信息--Class对象 一.RTTI概要 1.类型信息RTTI :即对象和类的信息,例如类的名字.继承的基类.实现的接口等. 2.类型信息的作用:程序员可以在程序运行时发现和使用类型信息. ...
- Thinking in Java -- 类型信息RTTI
Thinking in Java – 类型信息 个人感觉 java 中的比較难的部分了,在看了些netty源代码发现事实上这块很实用. 这章重点是RTTI和反射.先说下自己的理解 RTTI是执行时识别 ...
- Java类型信息(RTTI和反射)
要想在IT领域站得住脚,必须得不断地学习来强化自己,但是学过的技术不实践很容易便被遗忘,所以一直都打算开个博客,来记录自己学的知识,另外也可以分享给有需要的人! 最近在学习反射,为了更好地理解反射,就 ...
- Java 类型信息
<Thinking in Java 4th>第14章 类型信息 运行时类型信息(Run-Time Type Identification)使得你可以在程序运行时发现和使用类型信息. 14. ...
- Java 类型信息 —— 获取泛型类型的类对象(.class)
How to get a class instance of generics type T 考虑泛型类Foo<T>,在其成员中,如果想获取类型(type)T的类实例(class inst ...
- Java 类型信息详解和反射机制
本文部分摘自 On Java 8 RTTI RTTI(RunTime Type Information)运行时类型信息,能够在程序运行时发现和使用类型信息,把我们从只能在编译期知晓类型信息并操作的局限 ...
随机推荐
- redhat vim编辑器永久添加行号及搜索
设置行号: 跳转到home $ cd ~ 编辑.vimrc,没有的话自动创建 $ vim .vimrc 第一行加入: set nu :wq 保存退出,即可 如果想取消设置,同理删除set nu即可 v ...
- cocos2d JS-(JavaScript) 几种循环遍历对象的比较
通常我们会用循环的方式来遍历数组.但是循环是 导致js 性能问题的原因之一.一般我们会采用下几种方式来进行数组的遍历: 方式1: for in 循环: var arr = [1,2,3,4,5]; v ...
- maven的下载,安装配置以及build一个java web项目
一.下载 下载地址:http://maven.apache.org/download.cgi 二.安装 下载完成后,解压,进入到bin目录: 三.环境变量配置 复制bin目录下的文件的路径(如:xxx ...
- SpringMVC.入门篇《二》form表单
SpringMVC.入门篇<二>form表单 项目工程结构: 在<springmvc入门篇一.HelloWorld>基础上继续添加代码,新增:FormController.ja ...
- Java之.jdk安装-Linux
Jdk安装-Linux 1. 使用管理员,创建一个用户(charles),指令:useradd charles 2. 给创建的用户,添加密码(密码自己指定),指令:passwd charles 注意: ...
- 关于toolchain(工具链)的一点知识
之前一直觉得toolchain是个高大上的东西,现摘录 uClibc中的FAQ以助理解. A toolchain consists of GNU binutils, the gcc compiler, ...
- org.joda.time.DateTime 日期格式
最近一直在使用Java,偶尔一次遇到日期(util)的格式转换,心里还是规矩的写着记忆里面的代码,但是在自己测试的时候发现不正确,具体看了下代码,发现这里使用jota的方式编写,顺道查了一下,做了笔记 ...
- centos下mysql 5源码安装全过程记录
参考:http://blog.csdn.net/mycwq/article/details/24488691 安装cmake,mysql 5.5以后的版本要通过cmake进行编译 在新装的CentOS ...
- JavaScript--常用的输出方式
1.alert("要输出的内容"); 在浏览器中弹出一个对话框,然后把要输出的内容展示出来 2.document.write("要输出的内容"); ...
- jQuery事件--blur()和focus()
blur([[data],fn]) 概述 当元素失去焦点时触发 blur 事件. 这个函数会调用执行绑定到blur事件的所有函数,包括浏览器的默认行为.可以通过返回false来防止触发浏览器的默 ...