Class对象:class对象包含了与类有关的信息,每个类都有一个Class对象,每当我们编写并且编译了一个新类就会产生一个Class对象。
Class作用:用来创建一个类的实例(对象),执行RTTI(运行时类型信息);
Class.foName():通过该方法,获得一个类的Class对象的引用。从而可以在运行时使用类型信息。从而在对象还没有没有被new的时候去执行所有的静态域(包括静态域的初始化)。
package com.package14;class Candy {static {System.out.println("gandy 糖果");}}class Gum {static {System.out.println("Gum 口香糖");}}class Cookie {static {System.out.println("cookie 曲奇");}}public class SweetShop {public static void main(String[] args) {System.out.println("inside main");new Candy();System.out.println("After creating Gandy");try {//手动去加载Gum类,从而在运行时使用该类的类型信息(加载类中的静态域)Class.forName("com.package14.Gum");} catch (ClassNotFoundException e) {System.err.println("not found Gum");}System.out.println("After Class.foName()");new Cookie();System.out.println("After creating Cookie");}}
同时,使用Class。forName或一个类的Class引用后,该引用将会被加载到内存中去,以备我们去实例化。<br /> 获取详细的类型信息:<br /> 1.获取类中的信息:
interface HasBatteries { }interface Waterproof { }interface Shoots { }class Toy { Toy() { }Toy(int i) { }}class FancyToy extends Toy implements HasBatteries, Waterproof, Shoots {FancyToy() { super(1);}}public class ToyTest {static void info(Class cc) {//通过类Class 对象拿到该类的类型信息System.out.println("Class Name:" + cc.getName());System.out.println("Class is interface:" + cc.isInterface());System.out.println("Simple name:" + cc.getSimpleName());System.out.println("Canonical name" + cc.getCanonicalName());}public static void main(String[] args) {Class c = null;try {c = Class.forName("com.package14.FancyToy");} catch (ClassNotFoundException e) {System.out.println("Can't find FancyToy");System.exit(1);//参数不为0是停止虚拟机}info(c);//获得FanyToy类的类型信息
获取类的继承体系(从下往上)
1.获取类实现的接口:
①先拿到类的Class对象②:使用getInterfaces方法
package com.package14;interface HasBatteries { }interface Waterproof { }interface Shoots { }class Toy { Toy() { }Toy(int i) { }}class FancyToy extends Toy implements HasBatteries, Waterproof, Shoots {FancyToy() { super(1);}}public class ToyTest {static void info(Class cc) {//通过类Class 对象拿到该类的类型信息System.out.println("Class Name:" + cc.getName());System.out.println("Class is interface:" + cc.isInterface());System.out.println("Simple name:" + cc.getSimpleName());System.out.println("Canonical name" + cc.getCanonicalName());}public static void main(String[] args) {Class c = null;try {c = Class.forName("com.package14.FancyToy");} catch (ClassNotFoundException e) {System.out.println("Can't find FancyToy");System.exit(1);//参数不为0是停止虚拟机}info(c);//获得FanyToy类的类型信息System.out.println("该类中实现的接口有");//拿到fancyToy类中实现的接口for (Class cInterface : c.getInterfaces()) {System.out.println(cInterface);}
2.获取超类信息(父类):
①:获得该类的Class对象②:使用getSuperclass方法拿到父类③:newInstance()创建父类,然后在拿取父类的信息
public class ToyTest {static void info(Class cc) {//通过类Class 对象拿到该类的类型信息System.out.println("Class Name:" + cc.getName());System.out.println("Class is interface:" + cc.isInterface());System.out.println("Simple name:" + cc.getSimpleName());System.out.println("Canonical name" + cc.getCanonicalName());}public static void main(String[] args) {Class c = null;try {c = Class.forName("com.package14.FancyToy");} catch (ClassNotFoundException e) {System.out.println("Can't find FancyToy");System.exit(1);//参数不为0是停止虚拟机}Class superclass = c.getSuperclass();//获得该类的父类Object obj=null;System.out.println("父类的类信息为:");try {obj=superclass.newInstance();//创建父类} catch (InstantiationException e) {System.out.println("实例化异常");System.exit(1);} catch (IllegalAccessException e) {System.out.println("访问异常");System.exit(1);}info(obj.getClass());//拿到父类的信息}}
使用类时的三部曲:
加载.class的时候不会执行初始化
加载:由类加载器执行,会去查找类的字节码,并从这些字节码中创建一个Class对象链接:验证类的字节码,并为静态域没分配空间初始化:执行初始化,先父类的静态域、子类静态域,然后父类普通域、构造器。子类普通域、构造器
对静态域的调用会执行静态域的初始化操作,对于常数静态域的掉用则不会。静态常数可以在高并发的时候随意使用
package com.package14;class StaticDemo1{static final int SFI= 47;static{System.out.println("执行初始化11111");}}class StaticDemo2{static int SFI= 47;static{System.out.println("执行初始化11111");}}public class ClassInitallization2 {public static void main(String[] args) {System.out.println(StaticDemo1.SFI);System.out.println(StaticDemo2.SFI);}}
泛化的class引用
class的引用表示的就是他所指的对象的确切类型,我们也可以使用泛型,对其所指的类型进行限定。
注意:每个类的Class对象都是不同的,所以对有继承关系的类来说,他们的Class对象之间没有继承关系
package com.package14;public class GenericClasss {public static void main(String[] args) {Class<Integer> ints = int.class;Class integerClassass = int.class;//同一个对象的Class对象相等System.out.println(ints==integerClassass);//Integer虽然是Number的子类,但他们的Class对象并不能这样指定,以下代码报错//Class<Number> numberClass = Integer.class;//只能通过泛型边界符来指定Class<?extends Number> numberClass1 = Integer.class;}}/*===========================================================================*/package com.package14;class Goo{}class SubGoo extends Goo{}class SubGoo2 extends Goo{}class SubGoo3{}public class GenericClassReferences {public static void main(String[] args) {//SubGooClass 和GooClass没有继承关系Class<? extends Goo> subGooClass = SubGoo.class;//通过通配符可以指定subGooClass=SubGoo2.class;//也可以指定其他//subGooClass=SubGoo3.class;//不在一个继承体系不可以,除非通配符指向Object}}
