类字面常量
Java 还提供了另一种方法来生成Class对象的引用:使用“类字面常量(class literal)”。对上述程序来说,看起来就象下面这样:
FancyToy.class;
这样做不仅更简单,而且更安全,因为它在编译期就会受到检查。并且它无需方法调用,所以也更高效。
类字面常量不仅可以应用于普通的类,也可以应用于接口、数组以及基本数据类型。以外,对于基本数据类型的包装类,还有一个标准域TYPE。TYPE域是一个引用,指向对应的基本数据类型的Class对象,如下所示:
boolean.class Boolean.TYPE 等
我建议使用”.class”的形式,以保持它们与常规类的一致性。
注意,有一点很有趣,当使用“.class”来创建对Class对象的引用时,不会自动地初始化该Class对象。为了使用类而作的准备工作实际包括三个步骤:
1. 加载,这是由类加载器执行的。该步骤将查找字节码,并从这些字节码中创建一个Class对象。
2. 链接。在链接阶段将验证类中的字节码,为静态域分配存储空间,并且如果必须的话,将解析这个类创建的对其他类的所有引用。
3. 初始化、如果该类具有超类,则对其初始化,执行静态初始化器和静态初始化快。
Class initable = Initable.class;
System.out.println(initable.staitcFinal);
初始化有效地实现了尽可能的“惰性”。从对initable引用的创建中可以看到,仅使用.class语法来获得对类的引用不会引发初始化。但是为了产生Class引用,Class.forName()立即就进行了初始化,就像在initable3引用的创建中所看到的。
如果一个static final值是“编译器常量”,就像Initable.staticFinal那样,那么这个值不需要对Initable类进行初始化就可以被读取。但是,如果只是将一个域设置为static和final的,还不足以确保这种行为,例如,对Initable.staticFinal2的访问将强制进行类的初始化,因为它不是一个编译器常量。
如果一个static域不是final的,那么在对它访问时,总是要求在它被读取之前,要先进行链接和初始化,就像在对Initable2.staticNonFinal的访问中所看到的那样。
泛化的Class引用
Class引用总是指向某个Class对象,它可以制造类的实例,并包含可作用于这些实例的所有方法代码。它还包含该类的静态成员,因此,Class引用表示的就是它所指向的对象的确切类型,而该对象便是Class类的一个对象。
下面这两种语法都是正确的:
public static void main(String[] args) {
Class intClass = int.class;
Class<Integer> genericIntClass = int.class;
genericIntClass = Integer.class;
intClass = double.class;
//genericIntClass = double.class //illegal
}
如果你想稍微放松点限制,应该怎么办呢?乍一看,好像可以这样:
Class<Number> genericNumberClass = int.class
这看起来似乎是其作用的,因为Integer继承自Number。
但是它无法工作,因为Integer Class对象不是Number Class对象的子类。
为了能在泛化的Class引用时放松限制,我使用了通配符,它是java泛型的一部分。通配符就是“?”,表示“任何事物”。因此,我们可以在上例的普通Class引用中添加通配符,并产生相同的结果:
public static void main(String[] args) {
Class<?> intClass = int.class;
intClass = double.class;
}
在java SE5中,Class<?>优于平凡的Class,即便它们是等价的,它表示你不是疏忽才这么做的。
为了创建一个Class引用,它被限定为某种类型,或该类型的任何子类型,你需要将通配符与extends关键字相结合,创建一个范围。因此,与仅仅声明Class<Number>不同们现在做如下声明:
public static void main(String[] args) {
Class<? extends Number> dounded = int.class;
dounded = double.class;
dounded = Number.class;
}
当你将泛型语法用于Class对象时,会发生一件很有趣的事情:newInstance()将返回该对象的确切类型,而不仅仅只是在ToyTest.java中看到的基本的Object。这在某种程度上有些限制:
public static void main(String[] args) {
Class<FancyToy> ftClass = FancyToy.class;
FancyToy fancyToy = ftClass.newInstance();
Class<? super FancyToy> up = ftClass.getSuperclass();
//this wont compile
//Class<Toy> up2 = ftClass.getSuperclass();
//Only produces Object;
Object obj = up.newInstance();
}
超类只能这样:Class<? super FancyToy> up = ftClass.getSuperclass();
不能:Class<Toy> up2 = ftClass.getSuperclass();
由于这种含糊性:up.newInstance()的返回值不是精确的类型,而是Object:
Object obj = up.newInstance();
新的转型语法
public static void main(String[] args) {
Building b = new House();
Class<House> houseType = House.class;
House h = houseType.cast(b);
h = (House)b;
}
Case()方法接受参数对象,并将其转化为Class引用的类型。新的转型语法对于无法使用普通转型的情况显得非常有用。
分享到:
相关推荐
第14章可能是关于特定主题的深入探讨,虽然具体的章节内容没有直接给出,但我们可以根据ASP.NET 2.0的核心特性来讨论一些可能涵盖的知识点。 1. **网站项目与Web应用项目**:ASP.NET 2.0引入了两种类型的项目模式...
第14章 请求上下文 第15章 保护你的ASP.NET应用程序 第16章 Web Part让网站个性化 第17章 Ajax无刷新技术 第18章 性能与安全 第19章 调试与错误处理 第20章 打包与部署 第21章 学成出师——...
- **对象复制与归档**:第十八章和第十九章探讨了对象复制和归档的相关技术。复制允许创建对象的副本,而归档则是将对象序列化为可持久化的格式,以便将来恢复或在网络上传输。 #### 三、Cocoa和iPhone SDK - **...
第十四章 JSP 与 JDBC 14-1 JDBC 简介 14-2 MySQL 的安装与使用 14-3 JDBC 连接 MySQL 14-4 JDBC 连接 MySQL 的中文问题 14-5 PreparedStatement 14-6 CallableStatement 14-7 JDBC 2.0 介绍与使用 14-8 JNDI - 数据...
XML和ADO.NET\r\n第9章 显示XML数据 \r\n第10章 SQL Server 2005的XML集成 \r\n第11章 使用ASP.NET 2.0和SQL Server 2005构建飞机订票系统 \r\n第12章 XML串行化 \r\n第13章 XML Web服务\r\n第14章 ASP.NET 2.0配置 ...
例如,外设厂家应重点关注第四章至第十章,而USB主机控制器应用则主要参考第四章至第七章和第九、十章。 #### 二、USB2.0的技术特点 ##### 2.1 设计目标 USB的设计目标主要是为了增强PC机的可扩展性、降低成本并...
- **第14章:Webtop管理API**(页码305):介绍如何使用Netcool/Webtop管理API (WAAPI)工具,以及如何向Netcool/Webtop服务器发送XML配置指令。 - **附录A:HTML地图参考**(页码341):提供HTML地图命令语言的参考...
第14章 生成高效的Web应用程序 14.1 Web应用程序简介 14.2 连接到数据库 14.3 在ASP.NET 1.0中与数据库进行交互时存在的问题 14.4 数据源控件简介 14.5 缓存往返的数据 14.6 分页 14.7 常见问题 第15章 SQL Server...
主机控制器的实现主要关注第四至第七章和第九、十章,设备驱动程序开发则主要涉及第四、七、九章。配合其他相关文档,如《Universal Serial Bus Device Class Specification》,开发者可以全面了解USB 2.0 并开发出...
主机控制器应用主要参考第四章至第七章和第九十章;USB设备驱动程序开发者主要参考第四、七、九章。 - **补充资料**:《Universal Serial Bus Device Class Specification》作为本书的补充材料,提供了更多关于特定...
14. **第十四章:会话、用户和注册** - Django 的认证系统详解。 - 用户会话的管理方法。 - 用户注册和登录流程的设计。 15. **第十五章:缓存机制** - Django 的缓存系统介绍。 - 不同类型的缓存存储选项。 ...
在第14章,你会了解到如何使用SharedPreferences和SQLite数据库来保存游戏进度和用户设置。此外,还会讲解如何利用Android的Intent机制来实现游戏的启动、暂停和恢复。 网络功能在许多游戏中扮演着重要角色,第15...
第14章 性能 485 14.1 简单的技术 485 14.1.1 对象处理 486 14.1.2 数据库连接 489 14.1.3 存储过程 489 14.1.4 强类型的集合 498 14.1.5 会话状态 499 14.1.6 视图状态 499 14.2 页面和代码 500 14.2.1 ...
示例描述:本章演示ASP.NET 2.0网站的预编译以及学习ASP.NET 2.0的前置知识。 WebSite文件夹 创建的ASP.NET 2.0 Web站点。 www文件夹 第一个用C#开发的Web应用程序。 bianyi.bat 编译网站的批处理文件。 ...
第14章 ASP.NET AJAX相关技术简介 14.1 Ajax概述 14.1.1 什么是Ajax 14.1.2 Ajax的工作原理 14.1.3 Ajax的优势与不足 14.2 ASP.NET AJAX 14.2.1 ASENET AJAX的特性 14.2.2 ASENET AJAX的安装 14.3 ASENET ...
第十四章专门讨论了安全方面的技巧,这对于任何.NET应用程序来说都是非常重要的。本章涵盖了如何防御SQL注入攻击等常见威胁,并提供了如何自定义Login控件以提高输入验证功能的方法。 #### 第15章:创建自己的窍门...
**第十一节:习题** 为了加深对面向对象的理解,本节提供了一系列习题供读者练习。 #### 第二章:UML入门 **第一节:UML的发展历史** - **起源**:UML(Unified Modeling Language,统一建模语言)是由Grady ...