在Java的思想里面,万事万物皆对象:
其中类也是对象,所有的类都是一个Class对象,可以通过 类名.class 的方式获取该类的Class对象,也可以通过使用Class类的一个静态方法forName("全限定类名");的方式获取该类的Class对象,其中forName()方法当类名不存在的时候会抛出一个ClassNotFoundException异常,有趣的一点是,使用 类名.class 的方法类不会初始化,使用forName()方法 类会初始化。Class类的一些方法:
1.getName()和getCanonicalName()方法都会返回一个全限定类名(包含包名)
2.getSimpleName()该方法返回一个不包含包名的类名
3.getInterfaces()返回该类实现的所有的接口
4.isInterface()该类为接口时返回true,否则返回false;
5.getSuperclass();返回该类的直接父类的Class对象
6.newInstance();该方法能够在没有任何类型信息的情况下创建一个该类的实例,并返回一个Object对象,当然,在你可以发送Object能够接受的消息之外的任何消息之前,你更多的了解它并执行某种转型,该方法是实现虚拟构造器的一种途径,虚拟构造器允许你申明:“我不知道你的具体类型,但是无论如何你要正确的创建自己”。示例如下:
interface Run{}
interface Eat{}
interface Sleep{}
class People{
public int a = 10;
People(){}
People(int i){}
@Override
public String toString() {
return "this is a class People toString!";
}
}
class Man extends People implements Run,Eat,Sleep{
Man(){
super(1);
}
}
public class ClassTest {
public static void main(String[] args){
Class c = Class.forName("com.cuit.typeinfo.Man");
Class up = c.getSuperclass();
People people = null;
try {
people = (People) up.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(people.a);
Object obj = null;
try {
obj = up.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(obj.toString());
}
}
在上例中我们并没有up的任何更进一步的类型信息,只知道他是一个Class引用,但我们利用newInstance()方法成功的获得了该类的实例,并在知道了他是People类的时候将其转型为People对象。
类字面常量:
为了使用类而做的准备工作实际包含三个步骤:
1.加载:由类加载器执行,创建一个Class对象
2.链接:为静态域分配存储空间,如果必须将解析这个类创建的对其他类的所有引用
3.初始化:如果该类具有超类,则对其初始化,执行静态初始化器和静态初始化块
关于初始化有以下几点:
1.初始化被延迟到了对静态方法(构造器隐式的是静态的)或者非常数静态域进行首次引用时才执行
2.关于 static 和 final 关键字:如果一个值是编译期 常量并被声明为static final那么这个值不需要初始化便能读取,如果一个static域不是final的,那么对它访问时必须要先进行连接(为这个域分配存储空间)和初始化(初始化该存储空间)
泛型与Class:
当将泛型语法用于Class对象时,会发生一件有趣的事情:newInstance()方法会返回该对象的确切类型而不是基本的Object,但如果你手头是超类,则有一些不同,如下:
//Class<? super Man> 方式获得的Class对象在调用newInstance()方法时返回的是Object而不是Man的超类People
Class<People> c = People.class;
Class<? super Man> upp = c.getSuperclass();
try {
Object o = upp.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//当手头的是People的子类Man时,使用newInstance()方法返回People
Class<? extends People> tClass = Man.class;
try {
People people1 = tClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
类型转换:
当尝试向上转型时,编译器允许自由的做向上转型的赋值操作,二不需要做任何显示的转型操作
向下转型:
向下转型时,编译器将检查向下转型是否合理,因为他不允许向下转型到实际上不是待转型类的子类的类型上,可以使用关键字instanceof,它返回一个布尔值,告诉我们对象是否是某个特定类的实例
if(x instanceof Man){
//do something...
}
动态的instanceof: isInstance(T);