java 运行时类型识别(RTTI) - 1 - Class与instanceof
来源:互联网 发布:剑网三魔君捏脸数据 编辑:程序博客网 时间:2024/05/17 22:32
三种方式:
1.传统类型转换
2.查询Class对象
3.instanceof
1.传统类型转换
String string = (String) s;
2.查询Class对象
首先需要了解一下java.lang.Class这个类
类型信息在运行时的表示是有Class这个类的实例完成的
java使用Class对象来执行其RTTI,即使是类似转型的这样的操作
每个类都有一个Class对象(被保存在一个同名的.class文件中),为了生成这个类的对象,运行这个程序的JVM将使用被称为"类加载器"的子系统
(有关类加载器的内容,稍后介绍)
一旦某个类的Class对象被载入内存,它就被用来创建这个类的所有对象
- static{
- //...
- }
static{ //...}
这些代码在类第一次加载时执行
下面看看think in java中的示例代码
- public class Candy {
- static {
- System.out.println("Loading Candy");
- }
- }
public class Candy { static { System.out.println("Loading Candy"); }}
- public class Gum {
- static {
- System.out.println("Loading Gum");
- }
- }
public class Gum { static { System.out.println("Loading Gum"); }}
public class SweetShop {
- public static void main(String[] args) {
- System.out.println("inside main");
- new Candy();
- System.out.println("After creating Candy");
- try {
- Class.forName("Gum");
- } catch(ClassNotFoundException e) {
- e.printStackTrace();
- }
- System.out.println("After Class.forName(\"Gum\")");
- }
public static void main(String[] args) {System.out.println("inside main");new Candy();System.out.println("After creating Candy");try {Class.forName("Gum");} catch(ClassNotFoundException e) {e.printStackTrace();}System.out.println("After Class.forName(\"Gum\")");}}
运行结果
inside main
Loading Candy
After creating Candy
Loading Gum
After Class.forName("Gum")
Class仅在需要时加载,不然Loading Candy和Loading Gum应该在前面就输出了
这里要注意下Class.forName("Gum");
从log中看出,这句话也使得类Gum被加载了
生成Class引用可以用下面两种方式
1.newInstance()
newInstance使用的时候需要注意:
a.类需要有默认的构造器才可以,不然则会出现java.lang.InstantiationException
b.默认构造器必须能访问才行,不然会出现java.lang.IllegalAccessException
2.类字面常量
使用类字面量常量更简单,更安全:因为它在编译时被检查,所以也不需要try catch
并且使用类字面量不会初始化该Class
类字面量可以用于类、接口、数组、基本类型
对于基本数据类型的包装器类,有一个标准字段TYPE.TYPE是一个引用,指向对应的基本数据类型的Class
...等价于...boolean.classBoolean.TYPEchar.classCharacter.TYPEbyte.classByte.TYPEshort.classShort.TYPEint.classInteger.TYPElong.classLong.TYPEfloat.classFloat.TYPEdouble.classDouble.TYPEvoid.classVoid.TYPE3.instanceof
我们可以使用关键字instanceof来做类型检查(x instanceof Gum),它返回一个boolean
我们也可以使用动态的boolean java.lang.Class.isInstance(Object obj)来做类型检查
instanceof与Class的等价性
- public class Test {
- static class Base{}
- static class Derived extends Base{}
- static void test(Object x){
- System.out.println("Testing x of type " + x.getClass());
- System.out.println("x instanceof Base " + (x instanceof Base));
- System.out.println("x instanceof Derived " + (x instanceof Derived));
- System.out.println("Base.isInstance(x) " + (Base.class.isInstance(x)));
- System.out.println("Derived.isInstance(x) " + (Derived.class.isInstance(x)));
- System.out.println("x.getClass() == Base.class " + (x.getClass() == Base.class));
- System.out.println("x.getClass() == Derived.class " + (x.getClass() == Derived.class));
- System.out.println("x.getClass().equals(Base.class) " + (x.getClass().equals(Base.class)));
- System.out.println("x.getClass().equals(Derived.class) " + (x.getClass().equals(Derived.class)));
- }
- public static void main(String[] args) {
- Test.test(new Base());
- System.err.println("----------------------------");
- Test.test(new Derived());
- }
- }
public class Test {static class Base{}static class Derived extends Base{}static void test(Object x){System.out.println("Testing x of type " + x.getClass());System.out.println("x instanceof Base " + (x instanceof Base));System.out.println("x instanceof Derived " + (x instanceof Derived));System.out.println("Base.isInstance(x) " + (Base.class.isInstance(x)));System.out.println("Derived.isInstance(x) " + (Derived.class.isInstance(x)));System.out.println("x.getClass() == Base.class " + (x.getClass() == Base.class));System.out.println("x.getClass() == Derived.class " + (x.getClass() == Derived.class));System.out.println("x.getClass().equals(Base.class) " + (x.getClass().equals(Base.class)));System.out.println("x.getClass().equals(Derived.class) " + (x.getClass().equals(Derived.class)));}public static void main(String[] args) {Test.test(new Base());System.err.println("----------------------------");Test.test(new Derived());}}
结果
Testing x of type class Test$Base
x instanceof Base true
x instanceof Derived false
Base.isInstance(x) true
Derived.isInstance(x) false
x.getClass() == Base.class true
x.getClass() == Derived.class false
x.getClass().equals(Base.class) true
x.getClass().equals(Derived.class) false
----------------------------
Testing x of type class Test$Derived
x instanceof Base true
x instanceof Derived true
Base.isInstance(x) true
Derived.isInstance(x) true
x.getClass() == Base.class false
x.getClass() == Derived.class true
x.getClass().equals(Base.class) false
x.getClass().equals(Derived.class) true
可以看出:instanceof与isInstance()结果一样,equals和==的结果一样
instanceof是类型检查,==是对象比较,不考虑继承等关系.
个人觉得比较好理解
类加载器
这里只贴出笔记,之后在总结虚拟机的时候再详细说明,会在这里给出链接
- java 运行时类型识别(RTTI) - 1 - Class与instanceof
- java 运行时类型识别(RTTI) - 1 - Class与instanceof
- Java&&RTTI(运行时类型识别)
- 运行时类型识别(RTTI)
- RTTI 运行时类型识别
- 运行时类型识别(RTTI)
- 运行时类型识别RTTI
- RTTI 运行时类型识别
- RTTI 运行时类型识别
- RTTI 运行时类型识别
- RTTI 运行时类型识别
- RTTI运行时类型识别
- 运行时类型识别(RTTI)
- RTTI 运行时类型识别
- RTTI-运行时类型识别
- RTTI运行时类型识别
- RTTI运行时类型识别
- RTTI运行时类型识别
- Android项目中每个目录的作用
- 将二叉树叶子节点用rchild链成一个单链表
- providercontent监听器
- ARM-Tiny6410-裸机开发-Led && Button && Timer
- VC 判断指定进程是否已经启动
- java 运行时类型识别(RTTI) - 1 - Class与instanceof
- ios URL Scheme
- 支持与兼容性问题阻碍虚拟化部署
- linux块驱动程序分析 之 nand flash 驱动编写过程分析
- 老外最爱的个性短语集锦
- IOS文件下载
- Java零零碎碎的笔记(二)
- 动态绑定/解绑控件变量和控件
- 透明层覆盖在另一层上,透明层在ie6下不能响应事件的解决