网站首页 > 技术文章 正文
原文
5.9.1 Class 类
在程序运行期间,Java 运行时系统始终为所有对象维护一个运行时类型标识 (runtime type identification)。这个信息会跟踪每个对象所属的类。虚拟机利用运行时类型信息选择要执行的正确方法。
?不过,还可以使用一个特殊的 Java 类访问这些信息。保存这些信息的类名为 Class,这名字有些让人困惑。Object 类中的 getClass() 方法将会返回一个 Class 类型的实例。
Employee e;
//
Class cl = e.getClass();
?就像 Employee 对象描述一个特定员工的属性一样,Class 对象会描述一个特定类的属性。可能最常用的 Class 方法就是 getName。这个方法将返回类的名字。例如,下面这条语句:
System.out.println(e.getClass() + " " + e.getName());
?如果 e 是一个员工,则会输出:Employee Harry Hacker
?如果 e 是经理,则会输出: Manager Harry Hacker
?如果类在一个包里,包名也作为类名的一部分:
var generator = new Random();
Class cl = generator.getClass();
String name = cl.getName() ;// name is set to "java.util.Random";
还可以使用静态方法 forName 获得类名对应的class 对象
?
String className ="java.util.Random"
Class cl = Class.forName(className);
?如果类名保存在一个字符串中,这个字符串会在运行时变化,就可以使用这个方法。如果ClassName 是一个类名或接口名,这个方法可以正常执行。否则,forName 方法将抛出一个检查型异常 (checked exception)。无论何时使用这个方法,都应该提供一个异常处理器(exception handler)。关于如何提供异常处理器,请参见下一节。
?获得 class 类对象的第三种方法是一个很方便的快捷方式。如果T是任意的 Java 类型(或 void 关键字),T.class 将是匹配的类对象。例如:
?Class cll = Random.class; // if you import java,util.*;
?Class cl2 = int.class;
?Class cl3 = Double[].class;
请注意,class 对象实际上描述的是一个类型,这可能是类,也可能不是类。例如,int不是类,但 int.class 确实是一个 Class 类型的对象。
?注释:Class 类实际上是一个泛型类。例如,Employee.class 的类型是 Class<Employee>。我们没有深究这个问题,这是因为它会让已经很抽象的概念变得更加复杂。在大多数实际应用中,可以忽略类型参数,而使用原始的 Class 类。有关这个问题更详细的介绍请参见第8章。
?警告:鉴于历史原因,getName 方法对数组类型会返回有些奇怪的名字:Double[].class.getName() 返回“[Ljava.lang.Double;"。
int[].class.getName()返回[I" 。
?虚拟机为每个类型管理一个唯一的 Class 对象。因此,可以使用 == 运算符比较两个类对象。例如,
if(e.getClass() == Employee.class) ...
?如果e是一个Employee 实例,则这个测试将通过。与条件e instanceof Employee 不同,如果e 是某个子类 (如 Manager) 的实例,则这个测试将失败。
?如果有一个Class类型的对象,可以用它构造类的实例。调用 getConstructor 方法将得到个Constructor类型的对象,然后使用newInstance 方法来构造一个实例。例如:
var className ="java.ut1l.Random"; // or any other name of a class with// a no-arg constructor
Class cl = Class.forlame(className);
Object obj = cl.getConstructor().newInstance():
如果这个类没有无参数的构造器,则 getConstructor 方法会抛出一个异常。可以参见 5.9.7节了解如何调用其他构造器。
?注释:有一个已经废弃的 Class.toInstance 方法,它也可以利用无参数构造器构造一个实例。不过,如果构造器抛出一个检查型异常,那么这个异常将不做任何检查重新抛出。这违反了编译时异常检查的原则。与之不同,Constructor.newInstance 会把所有构造器异常包装到一个InvocationTargetException 中。
?C++注释: newInstance 方法相当于 C++ 中的虚拟构造器概念。不过,C++ 中的虚拟构造器不是一个语言特性,而是需要一个专业库支持的习惯用法。Class 类类似于 C++中的type_info类,getClass方法则等价于typeid操作符。不过,Java的Class 比 type_info功能更全面。C++的 type_info 只能给出表示类型名的一个字符串,而不能创建那个类型的新对象。
API java.lang.Class 1.0
- static Class forName(String className) 返回一个 Class对象,表示名为 className 的类
- Constructor getConstructor(Class... parameterTypes) JDK1.1 生成一个对象,描述有指定参数类型的构造器。参见 5.9.7 节了解如何提供参数类型的更多信息。
API java.lang.reflect.Constructor 1.1
- ?Object newInstance(Object... params) 将 params 传递到构造器,来构造这个构造器声明类的一个新实例。参见 5.9.7 节更多地了解如何提供参数。
API java,lang.Throwable 1.0
- void printStackTrace() 将 Throwable 对象和栈轨迹打印到标准错误流。
猜你喜欢
- 2024-09-20 Tomcat源码篇-简单到超乎想象的启动流程
- 2024-09-20 Java创建对象的6种方式(java什么是面向对象)
- 2024-09-20 java与数据库结合学习(java如何与数据库建立连接)
- 2024-09-20 「java设计模式」——代理模式(案例解析)
- 2024-09-20 反射魔镜:Java编程中的神秘力量,你真的会用了吗?
- 2024-09-20 Java反射详解(java反射的用法)
- 2024-09-20 JAVA基础(java基础题库及答案)
- 2024-09-20 java反射机制(Java反射机制主要提供了以下哪些功能)
- 2024-09-20 Java面试基础(java面试基础题及答案整理)
- 2024-09-20 同事跳槽到百度,总结的30道Java面试必问题目,限时领取
- 1514℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 562℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 507℃MySQL service启动脚本浅析(r12笔记第59天)
- 486℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 484℃启用MySQL查询缓存(mysql8.0查询缓存)
- 464℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 444℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 441℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)