三种方式:

1.传统类型转换

2.查询Class对象

3.instanceof

1.传统类型转换

String string = (String) s;

2.查询Class对象

首先需要了解一下java.lang.Class这个类

类型信息在运行时的表示是有Class这个类的实例完成的

java使用Class对象来执行其RTTI,即使是类似转型的这样的操作

类加载器"的子系统

类加载器的内容,稍后介绍)

一旦某个类的Class对象被载入内存,它就被用来创建这个类的所有对象


1. static{  
2. //...
3. }

static{
//...
}

这些代码在类第一次加载时执行

下面看看think in java中的示例代码


1. public class
2. static
3. "Loading Candy");
4. }
5. }

public class Candy {
static {
System.out.println("Loading Candy");
}
}



1. public class
2. static
3. "Loading Gum");
4. }
5. }

public class Gum {
static {
System.out.println("Loading Gum");
}
}

 public class SweetShop {


1. public static void
2. "inside main");
3. new
4. "After creating Candy");
5. try
6. "Gum");
7. catch(ClassNotFoundException e) {
8. e.printStackTrace();
9. }
10. "After Class.forName(\"Gum\")");
11. }


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.class

Boolean.TYPE

char.class

Character.TYPE

byte.class

Byte.TYPE

short.class

Short.TYPE

int.class

Integer.TYPE

long.class

Long.TYPE

float.class

Float.TYPE

double.class

Double.TYPE

void.class

Void.TYPE

3.instanceof

instanceof来做类型检查(x instanceof Gum),它返回一个boolean

boolean java.lang.Class.isInstance(Object obj)来做类型检查

instanceof与Class的等价性


1. public class
2. static class
3. static class Derived extends
4.
5. static void
6. "Testing x of type "
7. "x instanceof Base " + (x instanceof
8. "x instanceof Derived " + (x instanceof
9. "Base.isInstance(x) " + (Base.class.isInstance(x)));
10. "Derived.isInstance(x) " + (Derived.class.isInstance(x)));
11. "x.getClass() == Base.class " + (x.getClass() == Base.class));
12. "x.getClass() == Derived.class " + (x.getClass() == Derived.class));
13. "x.getClass().equals(Base.class) " + (x.getClass().equals(Base.class)));
14. "x.getClass().equals(Derived.class) " + (x.getClass().equals(Derived.class)));
15. }
16.
17. public static void
18. new
19. "----------------------------");
20. new
21. }
22. }

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_System

类加载器

这里只贴出笔记,之后在总结虚拟机的时候再详细说明,会在这里给出链接


java 运行时类型识别(RTTI) - 1 - Class与instanceof_System_02