反射(二)------Class类登场

上一节我们简单解释了:当我们在程序中构造一个对象时,不仅要在内存中存储对象的有效数据信息,还要在内存中存储对象所属的信息,这样在程序的运行过程中,JVM才可以正确的解析对象内存块中的数据。

那么问题来了,对象的类信息存储在哪里呢?在程序运行时是如何表示的呢?

首先回答第一个问题。在程序运行期间,所有的类信息都是存储在内存的方法区中。我擦!!!啥玩意是方法区啊?诶……要想知道什么是方法区,你要去看周志明老师的《深入理解Java虚拟机》的39页了。不过这里我们不讨论那么深,只需要知道:JVM按照不同的用途,将内存划分成多个区域。对象的类型信息就保存在方法区这个内存区域中。这个内存区域是所有线程共享的,也就是说,只要有一个线程把类型信息存储到内存中,整个程序的所有线程就都可以获取到类型信息了。

接着来回答第二个问题。在程序运行过程中,类信息是由Class对象表示的。在Java程序中,每个类都对应一个Class对象。下面我们就简单描述一下Class对象的构建过程:

首先,帅气的你写了一个java源文件Xxx.java,并熟练的javac编译源文件产生了Xxx.class文件。接着这个.class文件就静静的躺在硬盘里等待着施展自己才华机会的到来。只有你的程序用到Xxx类的时候,Xxx.class文件才会被读取到内存中,否则这个Xxx.class文件就一直躺在硬盘里,焦急的等待着。

终于,你的程序要构造一个Xxx类的对象了,这时候JVM发现,Xxx类还没加载到内存呢,用毛线来构造Xxx对象啊!!!于是JVM就根据Xxx这个类的名字,在ClassPath的指引下,开始寻找Xxx.class文件。终于在硬盘的某一个角落,JVM找到了正在哭泣的Xxx.class文件,于是就将Xxx.class文件读取到了内存之中。Xxx类高兴极了,因为它终于可以被派上用场了。

JVM将Xxx.class文件读取到内存中之后,就根据Xxx.class的内容,在内存中的方法区中创建了一个Class对象,这个Class对象包含了Xxx类的全部信息,JVM知道了类的信息,就可以创建Xxx的对象了。

过了不久,程序中又要构造一个Xxx对象了。JVM去内存中的方法区一看,我擦!!!Xxx类的Class对象正笑嘻嘻的在那等着呢。Xxx类的Class对象对JVM说:你直接用我就可以了,不用再去硬盘上找Xxx.class文件了。于是JVM就用这个Class对象,又构造了一个Xxx的对象实例,而没有去硬盘上去找Xxx.class文件。

可以看出,Java程序在它开始运行之前并不是加载所有的类,只有当这个类要被使用时才会被加载,也就是动态加载。我们做一个小实验:

import java.util.*;

public class Test
{
	public static void main(String[] args)
	{
		Scanner scan = new Scanner(System.in);
		int num = scan.nextInt();
		if(num == 1)
		{
			A a = new A();
		}
		else
		{
			B b = new B();
		}
	}
}

class A
{
	static
	{
		System.out.println("AAAAAA");
	}
}

class B
{
	static
	{
		System.out.println("BBBBBB");
	}
}
当类被加载时,会执行类中的静态代码块。根据输出内容,我们可以判断哪个类被加载了。程序比较简单,就是根据不同的输入内容,构造不同类的对象实例。当输入数字1时,可以看到只有A类被加载,而B类没有被加载。

另外,在加载一个类的时候,JVM的类加载器会首先检查该类的Class对象是否已经被加载到内存中,如果尚未加载,加载器才会去查找.class文件执行加载过程。看下面的例子:

import java.util.*;

public class Test
{
	public static void main(String[] args)
	{
		A a1 = new A();
		A a2 = new A();
		A a3 = new A();
		A a4 = new A();
		
	}
}

class A
{
	static
	{
		System.out.println("AAAAAA");
	}
}
从输出可以看出,虽然构造了多个A类的对象,但A类就只被加载了一次。

好啦,现在我们知道了,Class对象就包含了一个类的全部信息,那么我们该如何使用Class对象呢?先睡觉,明天继续大笑





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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值