Java的类与Class
先看一个例子
Animal.java
1 | public class Animal {} |
Cat.java
1 | public class Cat extends Animal { |
WhiteCat.java
1 | public class WhiteCat extends Cat { |
RTTI(Run-Time Type Identification) 运行时类型识别
在任何时刻,任何一个对象都清楚的知道自己是什么类型的。
Object.getClass()
在整个 java 运行期间 任何一个对象都可以在任何时候知道自己是什么类型的
1 | // 这个方法就是 |
一个Class 对象就是一个类的说明书
Class 和 类的关系
什么是 JVM ? 就是一个虚拟的计算机,所有的java代码都可以在里面跑。
我们平常写的 java代码是什么
(源代码)xxx.java 写完后经过 编译变成 xxx.class (也就是通常所说的字节码) 它是java跨平台的基石
jvm 可以跑 xxx.class 这样就实现了 一处编写,处处运行
JVM里有什么
- 栈 (方法栈)
- 堆 java中 所有的对象都是在 堆里 分配的
- new Cat() 的过程就是在 堆里创建
Cat 是如何创建的呢?
我想创建一个 Cat,它长什么样子有什么属性,这些东西存在那里?
这个信息就在堆里一个很奇怪的地方存着,叫做 class文件
一个Class对象就是一个类的说明书
1 | public class Cat extends Animal { |
此时当你 new Cat()
时候,JVM就会根据 Cat的说明书 把它创建出来。
1 | // 于是你疯狂造猫 |
这些猫 有什么共同点呢?
- 都是同一份说明书上生产出来的
- 每只猫都有独立的属性 leg / head / tail
public static int count
本质是什么 归属于 这份说明书的,每个 cat对象共享这份说明书。
这个Cat的说明书是什么?
- Class对象
- 静态变量归属于这个 Class对象
instanceof 瞬间豁然开朗
1 | obj instanceof Cat |
刚刚的Cat说明书在jvm内部开辟的一小块空间
它是非常特殊的,因为所有的类型基本上都只存在一份说明书
这个东西在 java7之前 叫做 永久代
java8之后叫做 元空间
将来你在工作的某一天迟早会碰到这样一个异常
- Java7之前叫做 OutOfMemory:PermGen
- Java8之后 叫做 MetaSpace
当你看到它们的时候,基本上是你的类出问题了
总结
每个对象创建出来的时候都需要一份说明书。
一个Class对象就是一份说明书,
因此你总是可以问一个对象obj.getClass()
你是从哪里装配出来的
然后对象说,我是从这个类 装配出来的,这就是 Class 文件的本质。
因此 你很容易实现 instanceof
判断
强制类型转换
1 | Object obj = new WhiteCat(); |
为什么报错?
首先强制类型转换本来就是不安全的,编译器允许你这样做
但是它在运行时会出问题,因为每个对象都清楚的知道自己是从什么对象创建出来的。
所以会报错