一、代码
class helloworld
{
public static void main(String[] args)
{
String s;
s = "helloworld";
System.out.println(s);
System.out.println(args);
}
}
二、解析
01.整体认识
Java源文件(*.java) --> Java编译器 --> 字节码文件(*.class) --> 类装载器 --> 字节码校验器 --> 解释器 --> 操作系统
解析1.类装载器
装载:Java虚拟机装载指定的CLASS文件(代码执行需要用到的类文件)
目的:形成这个CLASS类的实例对象
过程:java虚拟机使用类装载器定位到相应的CLASS文件,然后读取这个CLASS文件(一个线性二进制数据流),将它传入java虚拟机中。紧接着,虚拟机提取其中的类型信息。比如:该类的类名,方法名,变量名,修饰符,方法的返回类型等等。还有一个重要的东西就是常量池。(常量池保存了该类型的所有常量,包括直接常量和对其他类型,字段,方法的符号引用)将这些信息保存在一个叫做方法区的地方。最终形成CLASS类的实例,这个实例存放在内存的堆区。它成为了java程序与内部数据结构之间的接口,程序要访问该类型的信息,程序就调用该类型对应的CLASS实例对象的方法。简而言之:这个过程就是把一个类型的二进制数据解析为方法区中的内部数据结构,并在堆上建立一个CLASS对象的过程。
示例:装载Main类
Class文件:
1.Helloworld.class
2.String.class
3.System.class
Java虚拟机读取Main类的CLASS文件,生成对应的java.lang.Class类的实例,读取其中的类型信息,比如修饰符private,public,static,另外变量s、args共同构成了这个类的常量池。将这些信息保存在方法区。
解析2.内存分区
简易理解为: 1.栈区 2.堆区 3.方法
1.栈区
java虚拟机栈 描述的是Java方法执行的内存模型:
每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
即:栈中,
1.存方法(方法调用)先进后出的特点
2.存局部变量 作用范围结束,空间自动释放,无默认初始值,因此需要自己赋值初始化
局部变量表:存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(包含但不限于自身实例对象)。
2.堆区
Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。
即:堆中,
存放数组和对象 成员变量(因为有类对象在堆区创建,而成员变量属于类对象),有默认初始值
3.方法区
方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
即:方法区中,
存放
运行时常量池:用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。
02.代码解读
解析1.主方法
public static void main(String[] args) 基本写死了的
1.Public
目的:表示最大的权限,所有的对象都可以使用
2.Static
目的:可以由类名直接调用,主方法是程序的入口,它的调用不必经过类的实例化,所以要有static关键字修饰
3.Void
目的:返回值为空,主方法是一切的起点,不能返回重来,所以没有返回值
4.String[] args
目的:规定,主方法的形参必须声明为String[]类型的,args不要求
说明:String[]数组是用来接受运行时的参数
解析2.方法体
String s;
s = "helloworld";
System.out.println(s);
System.out.println(args);
1.String 类
2.System类
查看源码可知:
public final static InputStream in = null;
public final static PrintStream out = null;
public final static PrintStream err = null;
//private static volatile SecurityManager security = null;
包含 in out err 三个对象
3.System.out.println()方法
源码:
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
public void print(int i) {
write(String.valueOf(i));
}
public static String valueOf(int i) {
return Integer.toString(i, 10);
}
可知,System类的println()方法,实际重写了toString方法,
所以,
对于String类的s,打印出具体内容
对于String[] args,则打印 [Ljava.lang.String;@25203875
三、总结
1.对象访问
String s = "helloworld";
01.取出指定字符,生成地址
02.栈区创建变量s
03.把s指向指定地址(存储字符地址)
2.
01. 4个字节码文件
1.Helloworld.class
2.String.class
3.System.class
4.
02. 5个对象
1.Length() String[] args 空数组对象
2.String s
3.System.in
4.System.out
5.System.err
03. 2个变量
1.args ==>String []
2.s ==>String
04. 3个方法
1.main()
2.System.out.println()
3.toString()