JAVA 编程思想 第14章 类型信息
作者:互联网
JAVA 编程思想
第14章 类型信息
二级目录
三级目录
**运行时类型信息使的你可以在程序运行时发现和使用类型信息。
运行时识别对象和类的信息:
- “传统的”RTTI,它假定我们在编译时已经知道了所有的类型。
- 反射机制,允许我们在运行时发现和使用类的信息。**
14.1 为什么需要RTTI
- 面向对象编程中基本的目的:让代码只操纵基类的应用。
- RTTI:在运行时识别对象的类型。
14.2 Class
类的加载与创建对象时两个过程
引用和对象是两个概念
- 所有的类都是在对其第一次使用时,动态加载到JVM中的。
- 当程序创建第一个对类的 静态成员 的引用时,就会加载这个类。(静态成员:构造器/static)
package FancyToy;
interface HasBatteries{}
interface Waterproof{}
class Toy{
static{
System.out.println("加载Toy类");
}
Toy(){
System.out.println("实例化Toy");
}
Toy(int i){}
}
class FancyToy extends Toy implements HasBatteries, Waterproof{
static {
System.out.println("加载FancyToy类");
}
FancyToy(){
super(1);
System.out.println("实例化FancyToy");
}
}
public class ToyTest {
static void printInfo(Class cc){
System.out.println("---------------------------------");
System.out.println("Class name: "+cc.getName()+" is interface?[ "+cc.isInterface()+" ]");
System.out.println("Simple name: "+cc.getSimpleName());
System.out.println("Canonical name: "+cc.getCanonicalName());
}
public static void main(String[] args){
Class c = null;
try {
c = Class.forName("FancyToy.FancyToy");//加载一个类,c是Class对象的一个引用
FancyToy toy = new FancyToy();//实例化FancyToy对象个一个引用
printInfo(c);
} catch (ClassNotFoundException e) {
System.out.println("FancyToy 没有找到");
}
Class up = c.getSuperclass();
Object obj = null;
try{
obj = up.newInstance();//实例化引用。具体是实例化Class对象up的引用。
printInfo(obj.getClass());
}catch (InstantiationException e){
System.out.println("can not instantiate");
}catch (IllegalAccessException e){
System.out.println("can not access");
}
for (Class face : c.getInterfaces()){
printInfo(face);
}
}
}
//输出:
加载Toy类
加载FancyToy类
实例化FancyToy
---------------------------------
Class name: FancyToy.FancyToy is interface?[ false ]
Simple name: FancyToy
Canonical name: FancyToy.FancyToy
实例化Toy
---------------------------------
Class name: FancyToy.Toy is interface?[ false ]
Simple name: Toy
Canonical name: FancyToy.Toy
---------------------------------
Class name: FancyToy.HasBatteries is interface?[ true ]
Simple name: HasBatteries
Canonical name: FancyToy.HasBatteries
---------------------------------
Class name: FancyToy.Waterproof is interface?[ true ]
Simple name: Waterproof
Canonical name: FancyToy.Waterproof
14.2.1 类字面常量
- 使用“.Class”来创建Class对象的引用,不会自动初始化该Class对象。
- 初始化被延迟到了对静态方法的或者静态域进行首次引用时才执行。
package ClassInitialization;
class Initable{
static int i = 47;
static String s;
static {
s = "加载Initable";
System.out.println(s);
}
static void show(){
System.out.println("执行Initable的static方法");
}
}
public class ClassInitialization {
public static void main(String[] args) {
Class initable = Initable.class;//.Class会创建引用,但是不会初始化
System.out.println(".Class会创建引用,但是不会初始化----------------------------------");
System.out.println(initable.getSimpleName());//证明已经有引用了,但是类的静态方法并没有被调用
System.out.println("初始化延迟到了静态方法首次被调用的时候------------------------------");
Initable.show();
}
}
.Class会创建引用,但是不会初始化----------------------------------
Initable
初始化延迟到了静态方法首次被调用的时候------------------------------
加载Initable
执行Initable的static方法
- 如果直接调用类中的静态属性或静态方法,则会对类强制初始化
package ClassInitialization;
class Initable1{
static int i = 47;
static String s;
static {
s = "加载Initable";
System.out.println(s);
}
static void show(){
System.out.println("执行Initable的static方法");
}
}
public class ClassInitialization1 {
public static void main(String[] args) {
// Initable1.show();//此方法也可强制初始化
System.out.println(Initable.i);
}
}
加载Initable
47
14.2.2 泛化的Class的引用
package FancyToy;
interface HasBatteries{}
interface Waterproof{}
class Toy{
static{
System.out.println("加载Toy类");
}
}
class FancyToy extends Toy implements HasBatteries, Waterproof{
static {
System.out.println("加载FancyToy类");
}
}
public static void main(String[] args) throws IllegalAccessException, InstantiationException{
Class<FancyToy> ft = FancyToy.class;
FancyToy fancyToy = ft.newInstance();
// 按道理说,获得子类FancyToy的Class引用ft,从ft的getSuperclass方法可以获得父类Toy的class引用,实际上无法获得,语句编译时报错。
// Class<Toy> up = ft.getSuperclass();
Class<? super FancyToy> up = ft.getSuperclass();
// up.newInstance();返回的应该是Toy类的对象,但是该语句编译时报错
// Toy toy = up.newInstance();
Object toy = up.newInstance();
}
}
14.3 类型转换前先做检查
- instanceof
if(x indtanceof Dog)
// x为父类型的对象,向下转型前需确定对象是什么类型,返回值为boolean
标签:FancyToy,JAVA,14,类型信息,System,static,println,Class,out 来源: https://blog.csdn.net/YUELEI118/article/details/111352136