黑马程序员——Java语言加强部分——反射之Class类

------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

 一、Class类及其实例的理解 

        Java程序中的各个java类属于同一事物,描述这类事物的Java类名就是Class类。

例如

代码一:

interface PCI
{
	public void open();
	public void close();
}

class MainBoard
{
	public void run()
	{
		System.out.println("mainboard run ");
	}
	public void usePCI(PCI p)//PCI p = new NetCard()//接口型引用指向自己的子类对象。
	{
		if(p!=null)
		{
			p.open();
			p.close();
			
		}
	}
}


class NetCard implements PCI
{
	public void open()
	{
		System.out.println("netcard open");
	}
	public void close()
	{
		System.out.println("netcard close");
		//method();
	}
	
}

class Test5 
{
	public static void main(String[] args) 
	{
		MainBoard mb = new MainBoard();
		mb.run();
		mb.usePCI(null);
		mb.usePCI(new NetCard());
		
		
	}
}

           在上述代码中,接口PCI,类MainBoard,类NetCard,类Test5均属于Class类。

    Class类没有公共的构造方法。Class对象是在加载时由Java虚拟机及通过调用类加载器中的defineClass方法自动构造的。

    那么自动构造的具体的过程:类的二进制代码编译成class文件,放在硬盘上以后,把二进制代码加载到内存中,然后才可以创建一个个的对象。即一个类被类加载器加载到内存中,暂用一片存储空间,这个空间里面的内容就是类的字节码文件(class文件)。不同类的字节码是不同的,所以他们在内存中的内容是不同的,这一个个的空间可分别用一个个的对象来表示(注意:这一个个的对象是具有相同的类型)。简而言之,一个字节码文件对应一个class实例。Java应用程序通过编译会形成一个个的字节码文件(class文件),那么如上述代码一所示,编译该程序会产生4个字节码文件(Test5.class、   PCI.class、 MainBoard.class、  NetCard.class),即这里有4个Class实例对象。

     这里为什么是4个字节码文件?

     因为Class类的实例表示正在运行的Java应用程序中的类和接口

     枚举是一种类,注释是一种接口。每个数组属于被映射为Class对象的一个类,是多有具有相同元素的类型和为数的数组都共享该Class对象。基本的Java类型boolean、 byte、 char、 short、  int、 long、 float、 double和void也表示为Class对象。 

二、Class实例对象的获取

    获取的方法有三种:

1.类名.class   例如代码一中的MainBoard.class;适合于知道类名的情况

2.对象.getClass(); 适用于知道对象名的情况

3.Class.forName(字符串s);这种方法最灵活,只需要将完整类或者配置文件中的该项的值赋值给字符串s即可获取实例对象

           下面通过代码演示

    代码二

    

    String str = "abc";
    Class cls1 = str.getClass();
    Class cls2 = String.class;
    Class cls3 = Class.forName("java.lang.String");

    该代码以常见String类的字节码文件为例。

    那么Class对象cls1、 cls2、 cls3,这三个引用所指向的对象是否一致,也就是说他们是都指向的是同一块内存空间?

    代码三

             

    System.out.println(cls1 == cls2);
    System.out.println(cls1 == cls3);

    该代码运行结果都是true。也就是说这三个Class对象所指向的对象是一致的,所指向的是同一内存空间

那么如果是我们自己写的类,例如代码一中的类和获取的方法呢?获取方式也是可以采用这三种。

    假如是获取接口的实例对象或者字节码文件,那么第二种方法就不适用,因为我们知道接口不能创建对象。那么采取的方法就如代码五所示。

    代码四   

Class cls6 = PCI.class;
    Class cls7 = Class.forName("PCI");
    System.out.println(cls6 == cls7);
   

     PCI是一个接口,Class类中也提供了方法isInterface()来判定指定的 Class 对象是否表示一个接口类型。

注意:Class类中静态函数forName有两种:

1.       staticClass<?>   forName(String className)

返回与带有给定字符串名的类或接口相关联的 Class 对象。

2.       staticClass<?>   forName(String name,boolean initialize, ClassLoader loader)

使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class 对象。

 

上述代码中我们使用的是第一种,参数的值一般是我们在配置文件中设置的值,即我们会从配置文件中来获取。

三、九个预定的Class实例对象。

     有九种预定义的 Class 对象,分别是八个基本类型和 void。这些类对象由 Java 虚拟机创建,与其表示的基本类型同名,即 boolean、byte、char、short、int、long、float 和 double。

     这九种预定义的Class实例对象,即可以用基本类型.class等来表示,也可以用Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE,Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE(这些都是public static final 的变量)来表示。例如:int.class和Integer.class这两个实例对象不是一样的。

    在API中介绍Integer 类在对象中包装了一个基本类型 int 的值。Integer 类型的对象包含一个 int 类型的字段。该类中的静态字段TYPE就表示基本类型 int 的 Class 实例。因此int.class和Integer.TYPE这两个实例对象是一样的。

    此外:

在Class类中有个方法可以用来判断实例对象是否是基本类型:

public boolean isPrimitive()

判定指定的 Class 对象是否表示一个基本类型 

 总结:只要是源程序中出现的类型,都有各自的class实例。例如:int[]对应的实例对象是int[].class,不过int[].class是class实例对象数组,即Class[] mm=int[].class。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值