java 中 class 对象_Java 中 Class 类对象详解

Java 中 Class 类对象详解

Class 类简介:

在 java 世界里, 一切皆对象. 从某种意义上来说, java 有两种对象: 实例对象和 Class 对象.

每个类的运行时的类型信息就是用 Class 对象表示的. 它包含了与类有关的信息. 其实我们的实例对象就通过 Class 对象来创建的.

Java 使用 Class 对象执行其 RTTI(运行时类型识别, Run-Time Type Identification), 多态是基于 RTTI 实现的.

每一个类都有一个 Class 对象, 每当编译一个新类就产生一个 Class 对象, 基本类型 (boolean, byte, char, short, int, long, float, and double)有 Class 对象, 数组有 Class 对象, 就连关键字 void 也有 Class 对象(void.class).Class 对象对应着 java.lang.Class 类, 如果说类是对象抽象和集合的话, 那么 Class 类就是对类的抽象和集合.

Class 类没有公共的构造方法, Class 对象是在类加载的时候由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的, 因此不能显式地声明一个 Class 对象. 一个类被加载到内存并供我们使用需要经历如下三个阶段:

1. 加载, 这是由类加载器 (ClassLoader) 执行的. 通过一个类的全限定名来获取其定义的二进制字节流(Class 字节码), 将这个字节流所代表的静态存储结构转化为方法去的运行时数据接口, 根据字节码在 java 堆中生成一个代表这个类的 java.lang.Class 对象.

2. 链接. 在链接阶段将验证 Class 文件中的字节流包含的信息是否符合当前虚拟机的要求, 为静态域分配存储空间并设置类变量的初始值(默认的零值), 并且如果必需的话, 将常量池中的符号引用转化为直接引用.

3. 初始化. 到了此阶段, 才真正开始执行类中定义的 java 程序代码. 用于执行该类的静态初始器和静态初始块, 如果该类有父类的话, 则优先对其父类进行初始化.

所有的类都是在对其第一次使用时, 动态加载到 JVM 中的(懒加载). 当程序创建第一个对类的静态成员的引用时, 就会加载这个类. 使用 new 创建类对象的时候也会被当作对类的静态成员的引用. 因此 java 程序程序在它开始运行之前并非被完全加载, 其各个类都是在必需时才加载的. 这一点与许多传统语言都不同. 动态加载使能的行为, 在诸如 C++ 这样的静态加载语言中是很难或者根本不可能复制的.

在类加载阶段, 类加载器首先检查这个类的 Class 对象是否已经被加载. 如果尚未加载, 默认的类加载器就会根据类的全限定名查找. class 文件. 在这个类的字节码被加载时, 它们会接受验证, 以确保其没有被破坏, 并且不包含不良 java 代码. 一旦某个类的 Class 对象被载入内存, 我们就可以它来创建这个类的所有对象.

Dog.class,dog.getClass,Class.forName 区别:classDog{

// 存放在静态常量池

staticfinalStringname="Tom";

staticStringsex="Tom is man";

// 初始化是在类加载时进行的.

static{

System.out.println("Loading Tom");

}

}

classCat{

// 放在静态常量池

staticfinalStringname="Mark";

staticStringsex="Mark is man";

// 初始化是在类加载时进行的.

static{

System.out.println("Loading Mark");

}

}

publicclassClassInfo{

publicstaticvoidmain(String[]args)throwsClassNotFoundException,InstantiationException,IllegalAccessException{

System.out.println("-start dog-");

Classdog=Dog.class;//JVM 将使用类 Dog 的类装载器, 将类 Dog 装入内存(前提是: 类 Dog 还没有装入内存), 不对类 Dog 做类的初始化工作. 返回类 Dog 的 Class 的对象.

System.out.println("-----------");

System.out.println(Dog.name);

System.out.println("-----------");

System.out.println(Dog.sex);// 通过反编译得出, 此时初始化 Dog 对象.

System.out.println("-start Cat-");

Classcat=Class.forName("Cat");// 装入 Cat 类, 并做类的初始化.

System.out.println("-----------");

System.out.println(Cat.name);

System.out.println("-----------");

System.out.println(Cat.sex);

DogdaHuang=newDog();

ClassdaHuangClass=daHuang.getClass();// 返回引用 daHuangClass 运行时真正所指的对象 (因为: 儿子对象的引用可能会赋给父对象的引用变量中) 所属的类的 Class 的对象.

ClassxiaoBai=Cat.class;// 得到 class 对象

Catinstance=xiaoBai.newInstance();// 返回 cat 对象

// 使用 Class 对象的 newInstance()方法的时候, 就必须保证: 1, 这个 类已经加载; 2, 这个类已经连接了.

// 而完成上面两个步骤的正是 Class 的静态方法 forName()所完成的, 这个静态方法调用了启动类加载器, 即加载 java API 的那个加载器.

// new 关键字和 newInstance()方法的区别:

// newInstance: 弱类型. 低效率. 只能调用无参构造.

// new: 强类型. 相对高效. 能调用任何 public 构造.

}

}

Class 方法:ClassxiaoBai=Cat.class;

Stringname=xiaoBai.getName();// 获取类名

try{

// 将类对象转化为更具体的类型

Class<?extendsDog>aClass=xiaoBai.asSubclass(Dog.class);

}catch(ClassCastExceptione){

System.out.println(name+"不是类 Dog 的子类");

}

来源: http://www.bubuko.com/infodetail-3300709.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值