一.Class类
1.class Class对象描述了运行中的classes和interfaces。通过Class对象可以取得运行中的classes和interfaces的相关信息。
2.每个class都有一个相应的Class对象。每个class的Class对象存储于编译后的class所在的文件中。所以,当JVM装载一个.class文件时就会装载一个Class对象。所以,一个class只有一个Class对象。
二.Class类的基本应用
1.如何获取一个class的Class对象
1.1通过Class.forName(classname)方法,该方法接收一个String参数,用以指定要生成哪个class的Class对象.,如Class.forName(“Dog”)。
1.2通过类字面常量(class literals)来获得。
1)字面常量的形式为:classname.class。如Dog.class。
2)对于基本类开,每种基本类型的外覆类都有一个名为TYPE的标准数据,能够产生一个指向相应的基本类型的Class对象的reference。如int.class等同于Integer.TYPE。
1.3通过Object.getClass()方法来获得,如
Dogdog=newDog();
dog.getClass();
1.4一个产生Class对象的例子
classCat{
Cat(){System.out.println("InitCat()");}
static{
System.out.println("LoadingCat");
}
}
classDog{
Dog(){System.out.println("InitDog()");}
static{
System.out.println("LoadingDog");
}
}
classDuck{
Duck(){System.out.println("InitDuck()");}
static{
System.out.println("LoadingDuck");
}
}
publicclassTest{
publicstaticvoidmain(String[]args){
System.out.println("inmain()");
newCat();
System.out.println("AftercreateCat()");
try{
Classc1=Class.forName("Dog"); //(1)
Classc2=Dog.class; //(2)
}
catch(ClassNotFoundExceptioncnfe){
cnfe.printStackTrace();
}
System.out.println("AfterClass.forName(\"Dog\")");
Duckd=newDuck();
System.out.println("AftercreateDuck()");
Classc3=d.getClass();
System.out.println("AfterClass.forName(\"Duck\")");
}
}
运行结果为:
inmain()
LoadingCat
InitCat()
AftercreateCat()
LoadingDog
AfterClass.forName("Dog")
LoadingDuck
InitDuck()
AftercreateDuck()
AfterClass.forName("Duck")
代码(1)(2)产生了class Dog的Class对象,但并没有产生class Dog对象。
**:产生一个class的Class对象不会导致产生一个class对象
2.用Classc对象进行类型比较
2.1.直接比较
两个Class对象不论是通过equals()函数还是直接用==运算符进行比较,比较的都是类型是否相同。
2.2.通过Class.isInstance(object)函数进行比较,如
classCat{}
classDog{}
classDuck{}
publicclassTest{
publicstaticvoidmain(String[]args){
Classc2,c3;
Duckd=newDuck();
c2=Dog.class;
c3=d.getClass();
System.out.println("c2.isIntance(d):"+(c2.isInstance(d)));
System.out.println("c3.isIntance(d):"+(c3.isInstance(d)));
}
}
运行结果为:
c2.isIntance(d):false
c3.isIntance(d):true
2.3.通过instanceof关键字进行比较。但是两个处于不同的继承体系中的类对象和Class对象进行比较,会产生编译错误。
classCat{}
classDog{}
classDuck{}
publicclassTest{
publicstaticvoidmain(String[]args){
Classc3;
//Objectd=newDuck(); (1)
Duckd=newDuck(); //(2)
c3=d.getClass();
System.out.println("dinstanceofDog:"+(dinstanceofDog));//(3)
}
}
由于Duck和Dog处于两个不同的继承体系中,所以代码(3)会发生编译错误。如果把代码(2)注释掉,并去掉代码(1)的注释,编译将通过。这是因为所有class都是继承自Object的,所以Object与Dog处于同一个继承体系中,可以进行比较。
2.4.综合实例
classBase{}
classDerived{}
publicclassTest{
publicstaticvoidtest(Objectx){
System.out.println("Testingxoftype"+
x.getClass());
System.out.println("xinstanceofBase"+
(xinstanceofBase));
System.out.println("xinstanceofDerived"+
(xinstanceofDerived));
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)));
}
publicstaticvoidmain(String[]args){
test(newBase());
test(newDerived());
}
}
运行结果为:
TestingxoftypeclassBase
xinstanceofBasetrue
xinstanceofDerivedfalse
Base.isInstance(x)true
Derived.isInstance(x)false
x.getClass()==Base.classtrue
x.getClass()==Derived.classfalse
x.getClass().equals(Base.class)true
x.getClass().equals(Derived.class)false
TestingxoftypeclassDerived
xinstanceofBasefalse
xinstanceofDerivedtrue
Base.isInstance(x)false
Derived.isInstance(x)true
x.getClass()==Base.classfalse
x.getClass()==Derived.classtrue
x.getClass().equals(Base.class)false
x.getClass().equals(Derived.class)true