第14章 类型信息/14.1 为什么需要RTTI
标签: | 作者:易学笔记 更多资料请联系微信或QQ:1776565180 |
- 为什么需要RTTI
- 什么是RTTI:RTTI是Run-Time Type Information(通过运行时类型信息 ),也就是在运行时使用和发现类的信息
- 源代码:
package typeinfo;
//: typeinfo/Shapes.java
import java.util.*;
abstract class Shape {
void draw() { System.out.println(this + ".draw()"); }
abstract public String toString();
}
class Circle extends Shape {
public String toString() { return "Circle"; }
}
class Square extends Shape {
public String toString() { return "Square"; }
}
class Triangle extends Shape {
public String toString() { return "Triangle"; }
}
public class Shapes {
public static void main(String[] args) {
List<Shape> shapeList = Arrays.asList(
new Circle(), new Square(), new Triangle()
);
for(Shape shape : shapeList)
shape.draw();
}
} /* Output:
Circle.draw()
Square.draw()
Triangle.draw()
*///:~
- 结果输出:
Circle.draw()
Square.draw()
Triangle.draw()
第14章 类型信息/14.2 Class对象
标签: | 作者:易学笔记 更多资料请联系微信或QQ:1776565180 |
- Class对象
- 概念:用于表示类型信息在运行时是如何表示的,用来创建类的所有常规对象的
- 功能:Java中用Class对象来执行其RTTI
- 特点:每一个类都有一个Class对象
- 原理:通过在Java虚拟机(JVM)中启动“类加载器”子系统,类加载器加载与类同名的.class文件,这一个过程就是将Class对象载入内存中
- Class对象的几种方法说明
- getName( ):获取包含包名的类名
- isInterface( ):判断是否为接口
- getInterfaces():获取Class对象包含的接口
- getSimpleName():仅仅获取类名
- getCanonicalName():获取包含包名的类名
- getSuperclass():获取基类Class对象
- newInstance():创建Class对象对应类的实例,调用默认的构造方法
- 获取Class对象的方式
- 例子一:通过Class.forName(包名+类名);
- 源代码:
package typeinfo;
//: typeinfo/SweetShop.java
//Examination of the way the class loader works.
import static mypackage.Print.*;
class Candy {
//static 子句在类第一次加载时被执行
static {
print("Loading Candy");
}
}
class Gum {
static {
print("Loading Gum");
}
}
class Cookie {
static {
print("Loading Cookie");
}
}
public class SweetShop {
public static void main(String[] args) {
print("inside main");
new Candy();
print("After creating Candy");
try {
//Class.forName通过类名获取Class对象的引用,如果已经存在则不再加载(比如:Class.forName("typeinfo.Candy");)
Class.forName("typeinfo.Gum");
} catch (ClassNotFoundException e) {
print("Couldn't find Gum");
}
print("After Class.forName(\"Gum\")");
new Cookie();
print("After creating Cookie");
}
} /*
* Output: inside main Loading Candy After creating Candy Loading Gum After
* Class.forName("Gum") Loading Cookie After creating Cookie
*/// :~
- 结果输出:
inside main
Loading Candy
After creating Candy
Loading Gum
After Class.forName("Gum")
Loading Cookie
After creating Cookie
- 源代码:
- 例子二:通过其它方式获取Class对象
- 源代码:
//: typeinfo/toys/ToyTest.java
// Testing class Class.
package typeinfo.toys;
import static mypackage.Print.*;
interface HasBatteries {}
interface Waterproof {}
interface Shoots {}
class Toy {
// Comment out the following default constructor
// to see NoSuchMethodError from (*1*)
Toy() {}
Toy(int i) {}
}
class FancyToy extends Toy
implements HasBatteries, Waterproof, Shoots {
FancyToy() { super(1); }
}
public class ToyTest {
static void printInfo(Class cc) {
print("Class name: " + cc.getName() + //获取包含包名的类名
" is interface? [" + cc.isInterface() + "]"); //判断是否为接口
print("Simple name: " + cc.getSimpleName());//仅仅获取类名
print("Canonical name : " + cc.getCanonicalName());//获取包含包名的类名
}
public static void main(String[] args) {
Class c = null;
try {
//获取Class对象
c = Class.forName("typeinfo.toys.FancyToy");
} catch(ClassNotFoundException e) {
print("Can't find FancyToy");
System.exit(1);
}
printInfo(c);
//获取Class对象包含的接口
for(Class face : c.getInterfaces())
printInfo(face);
//获取基类Class对象
Class up = c.getSuperclass();
Object obj = null;
try {
// Requires default constructor:
//创建Class对象对应类的实例,调用默认的构造方法
obj = up.newInstance();
} catch(InstantiationException e) {
print("Cannot instantiate");
System.exit(1);
} catch(IllegalAccessException e) {
print("Cannot access");
System.exit(1);
}
printInfo(obj.getClass());
}
} /* Output:
Class name: typeinfo.toys.FancyToy is interface? [false]
Simple name: FancyToy
Canonical name : typeinfo.toys.FancyToy
Class name: typeinfo.toys.HasBatteries is interface? [true]
Simple name: HasBatteries
Canonical name : typeinfo.toys.HasBatteries
Class name: typeinfo.toys.Waterproof is interface? [true]
Simple name: Waterproof
Canonical name : typeinfo.toys.Waterproof
Class name: typeinfo.toys.Shoots is interface? [true]
Simple name: Shoots
Canonical name : typeinfo.toys.Shoots
Class name: typeinfo.toys.Toy is interface? [false]
Simple name: Toy
Canonical name : typeinfo.toys.Toy
*///:~
- 结果输出:
Class name: typeinfo.toys.FancyToy is interface? [false]
Simple name: FancyToy
Canonical name : typeinfo.toys.FancyToy
Class name: typeinfo.toys.HasBatteries is interface? [true]
Simple name: HasBatteries
Canonical name : typeinfo.toys.HasBatteries
Class name: typeinfo.toys.Waterproof is interface? [true]
Simple name: Waterproof
Canonical name : typeinfo.toys.Waterproof
Class name: typeinfo.toys.Shoots is interface? [true]
Simple name: Shoots
Canonical name : typeinfo.toys.Shoots
Class name: typeinfo.toys.Toy is interface? [false]
Simple name: Toy
Canonical name : typeinfo.toys.Toy
- 源代码:
- 例子一:通过Class.forName(包名+类名);