Java语言既具有编译型语言的特征,又具有解释型语言的特征,Java程序要经过先编译后解释两个阶段。
高级语言的运行机制
📍编译型语言
使用专门的编译器,针对特定的平台(移植性差),将高级语言的源代码一次性编译成机器码,所以生成的可执行程序可以脱离开发环境独立运行,且程序运行效率通通常较高。C、C++属于编译型语言。
📍解释型语言
使用专门的解释器,将高级语言的源代码逐行解释成特定平台的机器码并立即执行的语言。是代码在执行时才被解释器一行行动态解析和执行,而不是在执行之前就完成全部编译。可以认为,每次执行解释型语言的程序都需要通过解释器进行一次编译,所以不能脱离解释器独立运行,且程序运行效率通通常较低。JavaScript、Python属于解释型语言。
📍主要区别
编译型语言在一次性编译后即可在特定的平台运行,解释型语言是在运行期间才逐行进行编译。所以前者运行速度快(先前在哪个平台编译的,就在哪个平台运行),后者跨平台性好(在当前选定的平台一边编译一边运行)。
Java程序的运行机制和JVM
Java语言比较特殊,程序需要先经过编译步骤,但编译后并不会生成特定平台的机器码,而是生成一种与平台无关的字节码(.class文件),这种字节码并不是可执行的,必须经过java特定平台的解释器来解释执行,生成特定平台的机器码。因此可以认为,Java既是编译型语言,也是解释型语言。
java程序的执行过程必须经过先编译、后解释两个步骤。
.java文件(javac编译)---> .class字节码文件(java解释执行【使用java虚拟机】) ---> 特定平台的机器码
Java语言里负责解释执行字节码文件的就是java虚拟机(JVM)。各个平台上的JVM是不相同的,但是这些JVM都向编译器提供相同的编程接口,编译器只需要面向虚拟机,生成虚拟机能理解的代码,最后由虚拟机来解释执行。
📍Java语言为什么能一次编译到处运行?
java不同的平台有不同的JVM。源代码是一次编译成字节码文件(*.class文件),再利用不同平台的JVM进行解释,所以能在各个平台执行,这也是java跨平台的原因
JDK JRE JVM
JDK是java标准版开发包,是一套用于开发java应用程序的开发包,包括Java编译器、Java运行时环境(JRE)以及常用的Java类库等。
JRE是Java运行时环境,是运行Java程序的必须条件,它包含了类加载器、字节码校验器、JVM等
JVM是Java虚拟机,用于解释与平台无关的字节码文件,生成特定平台的机器码
包含关系:JDK>JRE>JVM
一般来说,如果只是要运行Java程序,可以只安装JRE,但如果要开发Java程序,则需要安装JDK
安装JDK需要设置的环境变量
📍PATH环境变量
我们知道,java执行过程必须经过先编译、后解释,Java程序安装了JDK之后,我们尝试在命令行窗口输入java和javac命令,发现提示“不是内部或外部命令”。这是因为:
Windows操作系统根据Path(不区分大小写)环境变量来查找命令,Path环境变量的值是一系列路径,操作系统根据这些路径依次查找当前执行的命令,若命令不存在,则提示"不是内部或外部命令...”
Linux操作系统根据PATH(区分大小写)环境变量查找命令。
用户变量和系统变量的区别:用户变量只对当前用户有效,系统变量对所有用户有效,为减少自己所做修改影响其他人,可设置用户变量。不过如果用户变量和系统变量配置的路径中包含了同一个命令,优先执行系统变量的。
📍为什么是%JAVA_HOME%?
其实就是引用变量JAVA_HOME的值,方便动态切换jdk版本
📍为什么是bin目录?
java javac命令就存在jdk的bin目录里面
第一个Java程序
1、在记事本新建一个文本文件,输入如下代码
public class HelloWorld{
public static void main(String[] args){
System.out.println("hello world !");
}
}
2、编译生成字节码.class文件
命令学习:javac -d destdir srcFile
destdir表示生成的字节码放在哪里
命令执行:C:\Users\25426>cd Desktop
C:\Users\25426\Desktop>javac -d . HelloWorld.java
3、运行Java程序
📍需要先进入.class文件所在目录
📍然后输入运行命令
C:\Users\25426\Desktop>java HelloWorld
📍此时看到命令行窗口输出语句,也就是程序要求输出的语句,代表Java程序运行成功
hello world !
Java程序的基本规则
程序的组织形式
Java解释器规定,某个类必须包含main方法才能被解释器直接解释执行,main方法必须使用public static void来修饰,参数为String[] 类型,即Java虚拟机是从main方法开始解释执行的,main方法是Java程序的入口。
Java源文件的命名规则
📍扩展名必须是.java
📍文件名必须与public类的类名相同,因此java源文件只能有一个public类(一个源文件可以有多个类的,但只能有一个public)
Java9的G1垃圾回收器
内存泄漏:程序在申请内存后,无法释放已申请的内存空间,导致系统无法及时回收内存并且分配给其他进程使用。多次内存泄漏会导致内存溢出;
内存溢出:程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;
Java语言存在着垃圾回收机制,能够及时回收无用内存,减少内存泄漏。
Java程序的内存分配与回收都是由JRE在后台自动进行的。JRE负责回收不再使用的内存,这称为垃圾回收机制(GC)。
当一个对象不再被引用时,JVM按照特定的垃圾回收算法来实现内存自动回收。
JVM无论使用哪种垃圾回收算法,一般都要做两件基本的事情:
📍跟踪有用的对象,确定无用的对象
📍回收无用对象的内存空间
垃圾回收的特点:
📍垃圾回收器只能回收内存资源,不能回收物理资源,如数据库连接、磁盘IO
📍垃圾回收的时机不可预知,可能是CPU空闲时,也可能是内存不够用时。即使调用gc()或者System.gc(),也只是建议系统进行垃圾回收,但不一定会执行。
📍垃圾回收的开销会影响程序性能
程序编写原则:不再需要的对象,不要引用它们,那么它的内存有机会被收回
后续在详细介绍......