1. hello,world程序
//public表示公共的,说明其他代码中也可以使用这个公共的类
//class是java中的关键字,表示定义一个类
//Hello是类的名字,这个类写在Hello.java文件中,类的名字和文件名字保持一致
public class Hello{
//定义一个方法,方法的名字叫 main,方法的参数名字叫args,参数的类型是String[],表示字符串数组类
型
//public表示这是个公共的方法
//static表示这是个静态的方法
//void表示main方法执行完,没有任何返回值
public static void main(String[] args){
//main方法中,执行这个语句代码
//该代码表示使用System类中的out属性的println方法,将字符串"hello world"进行打印输出
System.out.println("hello world");
}
}
- main方法,jvm运行唯一入口,必须存在,类中定义,固定格式。
- java命令,会先启动JVM虚拟机,然后再进行加载、验证、解释/JIT、运行等一系列的过程。
1.1常用命令(控制台)
javac 编译命令
java 运行命令
javadoc 生成API文档命令
javap (-verbose:查看字节码详细信息) 反解析命令,可以解析出class字节码文件的内容
jar 打包命令
javac -d . Hello.java :java中编码命令中有参数,可以直接帮我们在指定位置自动创建和包名对应的目录结构,并且 把编译好的class文件自动存放到里面
javac -d bin Hello.java:也可以在指定的路径下,生成和包名对应的目录结构
java -cp ./bin com.briup.test.Hello:运行当前命令时,临时指定classpath路径
java -verbose Hello:JVM去启动运行Hello类之前,从rt.jar中加载的类的日志记录,重定向到txt:java -verbose Hello > a.txt
2. 命名空间(专有名词)
package其实就是类的命名空间,用来唯一标识这个类的,同时也把类似功能的类组织到一个包中。避免和的类的名字重复。(一般官网域名倒写)
- package com.briup.test 虽然生成文件com/briup/test但实际上相当于一个整体的命名com.briup.test.Hello因此运行要选择整体才可以运行。
- 自创文件夹test不能java test.Hello来运行,只能cd切包或者classpath修改来运行。
3. jar class文件集合体压缩
java中有jar命令,可以将一个或多个class文件,打包到一个指定的jar文件中(xxx.jar)
例如,jre中的rt(runtime).jar,就是将src.zip中的java源代码编译成class文件后,又将这些class文件打包到rt.jar中 的。
字节码文件信息:也可以使用javap -verbose Hello.class 命令其查看对应的JDK版本
其中,前面的CA FE BA BE表示当前class是java语言编译而成,这叫魔数,java代码编译成的class文 件中,最前面一定是这个值。
其中,00 00 00 34,这个表示当前class文件是那个版本JDK编译出来的。16进制的34 等于 10进制的 52 ,52代表的JDK1.8版本,51就是JDK1.7,依次类推
归类到jar包命令:
java -jar hello.jar:运行jar文件,要指定jar包中的运行路径Main-Class
jar -cvf hello.jar Hello.class:把当前目录中的Hello.class打到hello.jar这个jar包中
jar -cvf hello.jar Hello.class Word.class:把当前目录下的Hello.class 以及 World.class打到hello.jar 这个jar包中
jar -cvf hello.jar *.class:把当前目录下的所有的class打到hello.jar这个jar包中
jar -cvf hello.jar bin:把当前目录下的bin文件夹里面的所有文件打到这个jar包中,同时【包含】bin 目录本身
jar -cvf hello.jar -C bin .:把当前目录下的bin文件夹里面的所有文件打到这个jar包中,但是【不包 含】bin目录本身(主要用)
4.类加载器
java中的类,想要运行就必须把类对应的class文件加载到内存,JVM中真正负责加载class文件内容 的是类加载器
三种类加载器:
- 启动类加载器 bootstrapClassLoader,非java语言实现 为了使得一个类加载器可以使用
- 作用:加载指定路径中jar里面的class文件
- 扩展类加载器 ExtClassLoader,java语言实现,是ClassLoader类型的对象
- 作用:加载指定路径中jar里面的class文件( 只能是jar中存在的class)
- 应用类加载器 AppClassLoader,java语言实现,是ClassLoader类型的对象
- 作用:加载指定路径中class文件或者jar里面的class文件(用户自定义)
5. JVM 双亲委托机制
即加载自定义类的时候首先 应用类——>扩展类——>启动类——>启动类查找若无——>扩展类查找——>应用类查找。
例如:java com.briup.test.Hello 命令
- 现在要加载Hello.class文件中的类
- 首先加载任务就交给了AppClassLoader
- 然后AppClassLoader把这个任务委托给自己的父加载器,也就是ExtClassLoader
- 然后ExtClassLoader把这个任务委托给自己的父加载器,也就是bootstrapClassLoader
- 然后bootstrapClassLoader就尝试去加载Hello这个类,但是在指定路径下并没有找到
- 然后任务又交回给了ExtClassLoader,ExtClassLoader尝试加载Hello这个类,但是在指定路径中没找 到
- 然后任务又交回给了AppClassLoader
- 最后AppClassLoader从CLASSPATH中指定的路径里面找到并加载了这个Hello类,完成类加载的过程
6. 问题解答
-
Java中为什么写类
类是组织代码的基本单元,因此写一个类。
-
为什么要有main方法
程序唯一入口,固定,jvm识别
-
为什么可以直接使用System类
导包原则:同包下定义,或者lang包中定义调用的时候不用导包。
src.zip中java文件编译到jre下lib下的rt.jar包中,自动加载按需加载在程序运行时就加载到jvm中因此不需要导包。
-
如何找到Hello.class文件
先双亲委托,再由应用类配置CLASSPATH查找
-
Hello这个类的名字和Hello.java的名字有什么必然关系
文件名必须和公共类(Public)名字一致