//声明:部分内容引自《Java编程思想(第四版)》机械工业出版社
【Class 对象】
– RTTI: Run-Time Type Identification.
– 所有的类都是在对其第一次使用时,动态加载到 JVM 中的。构造器也是类的静态方法,使用 new 操作符创建类的新对象也会被当作对类的静态成员的引用。Java 程序的各个部分是在必需时才加载的。
练习1
在 ToyTest.java 中,将 Toy 的默认构造器注释掉,并解释发生的现象。
注释掉后,Toy 只有一个带参数的构造器,而使用 newInstance() 来创建的类,必须带有默认的构造器。
练习10
写一个程序,使它能判断 char 数组究竟是个基本类型,还是个对象。
package JT_practice;
/**
* Created by JT on 2016/7/9.
*/
public class Practice_14_10 {
public static void main(String[] args){
// char[] arr = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};
// System.out.println("isArray:" + arr.getClass().isArray());
// System.out.println("isPrimitive:" + arr.getClass().isPrimitive());
// System.out.println("isEnum:" + arr.getClass().isEnum());
// System.out.println("isAnnotation:" + arr.getClass().isAnnotation());
char[] c = new char[10];
// c is an Object:
System.out.println("Superclass of char[] c: " +
c.getClass().getSuperclass());
System.out.println("char[] c instanceof Object: " +
(c instanceof Object));
}
}
// 上半部分注释掉的代码是参考网上的方案写出的,下半部分是标准答案。
从结果可得,char 数组是一个对象。
– 类字面常量:生成对 Class 对象的引用。
– TYPE 字段是一个引用,指向对应的基本数据类型的 Class 对象,例如:int.class 等价于 Integer.TYPE。
– 当使用 “.class” 的形式来创建对 Class 对象的引用时,不会自动地初始化该 Class 对象。
– 放松泛化的 Class 引用的限制:Class<?> intClass = int.class;
【类型转换前先做检查】
– 已知的 RTTI 形式:
传统的类型转换,如 “(Shape)” ,由 RTTI 确保类型转换的正确性,如果执行了一个错误的类型转换,就会抛出一个 ClassCastException 异常。
代表对象的类型的 Class 对象。通过查询 Class 对象可以获取运行时所需的信息。
关键字 instanceof。返回一个布尔值,告诉我们对象是不是某个特定类型的实例。例:
if(x instanceof Dog)
((Dog)x).bark();
– 动态的 instanceof:Class.isTnstance()
【instanceof 与 Class 的等价性】
– 以 instanceof 的形式(即以 instanceof 的形式或 isInstance() 的形式,它们产生相同的结果)与直接比较 Class 对象的差别:instanceof 保持了类型的概念,它指的是:你是这个类吗,或者你是这个类的派生类吗?,而如果用 == 比较实际的 Class 对象,就没有考虑继承——它或者是这个确切的类型,或者不是。
【反射:运行时的类信息】
– RTTI 和反射的区别:
- 对 RTTI,编译器在编译时打开和检查 .class 文件。
- 对反射机制, .class 文件是在运行时打开和检查的。因为在编译时它是不可获取的。
– 类方法提取器:可以用一个额外的 char 、int 、或 String 等参数调用 java ShowMethods java.lang.String ,得到某个类的方法。
【动态代理】
– 可以动态地创建代理并动态地处理对所代理方法的调用。在动态代理上所做的所有调用都会被重定向到单一的调用处理器上,它的工作是揭示调用的类型并确定相应的对策。