🥅对Java的加载与执行的理解
❤️从图可以得出Java 程序从开发到最终运行是这样进行的:
⭐️第一步(写代码):在任意位置创建一个.java 结尾的文件,程序员在该文件中编写符合 Java 语法的源代码,这个文件被称为Java 源文件。
⭐️第二步(编译):使用“javac”命令对 java 源文件进行编译,如果 Java 源文件符合 Java 语法规则,则编译生成 1 个或者多个以“.class”结尾的文件。
“.class”结尾的文件我们称之为字节码文件,注意字节码文件不是普通文本文件,使用记事本等文本编辑器是无法打开的, 但该文件内容也不是二进制,如果是二进制形式的话,操作系统是可以直接执行的,这个文件 的内容我们称之为字节码。
注意:这里有一个“类名”的概念,假设生成的文件是 A.class, 则表示类名为 A,B.class 则表示类名为 B。
⭐️第三步(运行):使用“java”命令运行已编译的Java程序,假设编译之后的字节码文件 是 A.class,则在 dos 命令窗口中执行 java A命令,这个时候 Java 虚拟机(JVM)就启动了, Java 虚拟机(JVM)通过“类装载器 ClassLoader”从硬盘中找到 A.class 文件并装载,字节码文件被装 载到Java虚拟机之后,Java 虚拟机解释器对字节码进行解释,最终解释为二进制码,然后操 作系统通过执行二进制指令来和硬件平台完成交互。
❤️ java程序从编写到最终运行经历了非常重要的两个阶段:
⭐️编译阶段
⭐️运行阶段
❤️注意1:java程序员直接编写的java代码(普通文本)是无法执行被JVM识别的。
⭐️java程序员编写的java代码这种普通文本必须经过一个编译,将这个
"普通文本代码"变成字节码”,JVM能够识别“字节码”。
❤️java代码这种普通文本被称为:java源代码。(自己编写的代码是源代码)
⭐️java代码这种普通文本变成字节码的过程,被称为:编译。
⭐️源代码不能直接执行,需要先进行编译,生成源代码对应的“字节码”,
JVM可以识别的是字节码。
❤️问题1:编译阶段和运行阶段可以在不同的操作系统上完成吗?
⭐️答:在windows上编译,编译之后生成了“字节码”,把“字节码”放到linux上运行
完全可以, 因为Java是跨平台的。可以做到一次编写到处运行。
❤️问题2:java源代码一旦编译之后,源代码可以删除吗?只留下字节码可以执行吗?
⭐️答:可以执行,因为源代码不参与程序的执行过程。参与程序执行过程的是字节码。
但是最好不要删除源代码。有可能会用到源码进行重编译
❤️放源代码的文件扩展名必须是:xxx.java,并且需要注意的是:编译生成的字节码文件
⭐️扩展名是:xxx.class
.java文件就是源文件,这个文件中编写源代码。
.class文件就是字节码文件,这个文件是编译源代码而得到的。
❤️注意:
⭐️1个java源文件是可以编译生成多个.class文件的。最终运行的是.class文件。
❤️问题3:字节码文件是二进制文件吗?
⭐️答:字节码文件不是二进制文件。如果是二进制的话,就不需要JVM了。
因为操作系统可以直接执行二进制。
❤️问题4: java程序从开发到最终运行经历了什么?
⭐️编译期:(可以在windows上)
第一步:新建一个xxx.java文件,并打开
第二步:在xxx.java文件中编写“符合java语法规则的”源代码。并保存
第三步:使用编译器(javac【JDK安装后自带】)对xxx.java文件进行编译。
编译通过了才会生成.class字节码文件。并且一个java源文件是可以
生成多个.class文件的。(编译实质上是检查语法)
⭐️ 运行期(JRE在起作用):(可以在windows上,也可以在其他的OS上。)
第四步:如果是在Linux上运行,需要将windows上生成的.class文件拷贝过去,不需
要拷贝源代码,真正运行的是字节码。(但是源代码也不要删除)
第五步:使用JDK自带的一个命令/工具:java(负责运行的命令/工具)执行字节码
第六步:JVM虚拟机的操作
JVM会将字节码文件装载进去,然后JVM对字节码进行解释
(解释器负责将字节码解释为1010..等的二进制)
第七步:JVM会将生成的二进制码交给操作系统(OS),操作系统会执行
二进制码和硬件进行交互。
❤️注意2:在以上的过程中,需要使用两个非常重要的命令?
javac 命令:负责编译
java 命令:负责运行
❤️注意3:
xxx.java源文件经过编译之后生成了A.class、B.class、C.class等文件,
那么我们称A是一个类、B是一个类、C是一个类。其中A、B、C是类的名字。
❤️总结: 编写、编译、运行
⭐️新建java文件,并打开
⭐️写java源代码并保存
⭐️javac命令编译
⭐️java命令运行
🏀4.第一个Java程序
🥅JDK的安装与配置
❤️安装JDK
⭐️先在orcale官网中下载,并进行安装,一定要记住安装路径!
⭐️对于JDK13安装的时候内置了一个JRE,独立于JDK之外的JRE并没有生成。
如果你希望生成一个独立于JDK之外的JRE的话需要执行特殊的命令。
⭐️注意的是:
JDK8安装的时候,不仅JDK内置了一个JRE,而且还会在JDK目录之外
独立的生成一个单独的JRE(以前低版本的时候,JRE实际上是有2个。)
一个是JDK内置的,一个是独立于JDK之外的。
⭐️JDK的bin目录下有:
javac.exe 负责编译
java.exe 负责运行
❤️环境的配置
⭐️安装好JDK我们直接代开dos窗口,输入javac -version居然发现并不能用!
这是因为javac不是内部命令,我们没有配置环境变量。
⭐️这很类似于Linux中我们配置环境变量PATH!在Linux中,命令、程序、
工具可简单理解为可执行程序!既然是可执行程序,那么就可以直接运行!
⭐️那么我们通过gcc编译的可执行文件a.out,为什么不能像常用命令ls
那样直接就可以运行呢?因为ls的绝对路径已经写到环境变量PATH里面了;
我们把a.out的路径也追加到PATH里就可以直接就能运行啦!
⭐️对于ipconfig用来查看IP地址,如果我们删除Path里面的%SystemRoot%\system32呢?
我们就会发现也会报错,因为我们把它的绝对路径从Path里面删除了!
最终还要把%SystemRoot%\system32添加回去到Path里面!
⭐️所以我们只需要把javac这个命令的绝对路径写到环境变量Path里就可以啦!
也就是安装的JDK下的bin路径里有javac命令,
比如我的:C:\Program Files\Java\jdk-13.0.2\bin 配置到环境变量path当中
⭐️详细步骤:【此电脑】右击鼠标属性---》【相关设置】高级系统设置---》
【环境变量】---》【系统变量】找到Path,把上面的路径加进去就行!
⭐️重新打开dos框,输入javac -version能显示版本说明就好了!
⭐️补充1:环境变量包括“系统变量”和“用户变量”
系统变量:范围比较大,系统变量会让计算机所有用户都起作用
用户变量:范围比较小,这个变量只是作用于当前用户
⭐️补充2:
怎么查看编译器版本?javac -version
怎么查看java虚拟机的版本?java -version
⭐️补充3:
如果把路径和其它路径配置到一块,路径和路径之间必须采用“半角的分号”分隔。
🥅程序的编译
❤️比如我们写一个HelloWord程序,具体代码分析后面再讲!
⭐️创建一个HelloWorld.java文件,并写入:
❤️怎么编译呢?
⭐️方法1:
首先在dos命令窗口,用cd切换目录,进入HelloWorld.java文件所在的文件夹,
然后输入javac HelloWorld.java进行编译;但是这样切换目录,是不是很麻烦?很难记住目录?
⭐️方法2:
输入cd,然后直接进行拖拽,把HelloWorld.java所在的目录直接拖拽到dos命令窗口,就会直接切入到所需目录,例如:
⭐️方法3:
在当前HelloWorld.java文件目录下的最上面显示路径的地址栏上,输入cmd回车就可以点开dos窗口,并且路径是当前路径!
❤️javac 源文件
⭐️javac HelloWorld.java进行编译,最终就会生成一个.class文件(字节码文件)!
🥅程序的运行
❤️运行的前提是:class文件(字节码)生成了。没有字节码文件程序是无法运行的。
⭐️假设该文件的名字叫做:HelloWorld.class,HelloWorld 就是一个类名。
⭐️如果文件名是Test.class,那么:Test就是一个类名。
❤️怎么运行,使用哪个命令?
⭐️使用JDK的bin目录下的:java.exe命令来运行。
⭐️ java 类名,例如:java HelloWorld
❤️千万要注意:java这个命令,后面跟的是“类名”,而绝对不能跟“文件路径”,
⭐️因为java命令后面跟的不是文件,是一个“类名”。
❤️运行java程序需要哪些步骤呢?
⭐️第一步:先使用cd命令切换到HelloWorld.class文件所在的路径。
⭐️第二步:执行java HelloWorld
java命令后面只要是跟路径,就一定不行。
java命令后面只能跟类名!
🥅其它环境变量
❤️1、Path
⭐️到目前为止,我们学习了两个环境变量,一个是 windows 操作系统的 path 环境变量,另 一个是 java 语言的 classpath 环境变量;但只配置了一个环境变量Path,就能运行java代码了,并且这个环境变量Path和java实际上没关系,是windows操作系统的机制
❤️2、JAVA_HOME
⭐️对于Java的JDK所属的环境变量,有一个叫做:JAVA_HOME
⭐️JAVA_HOME目前我们不需要,不配置这个环境变量也不会影响当前java程序的运行。
学习JavaWeb的时候需要安装Tomcat服务器,那个时候JAVA_HOME就必须配置了!
❤️ “java HelloWorld”的执行过程以及原理。
⭐️cd进入当前目录:执行java HelloWorld,敲完回车,都发生了什么?
⭐️第一步:会先启动JVM(java虚拟机)
⭐️第二步:JVM启动之后,JVM会去启动“类加载器classloader”
类加载器的作用:加载类的。本质上类加载器负责去硬盘上找“类”对应的“字节码”文件。
假设是“java HelloWorld”,那么类加载器会去硬盘上搜索:HelloWorld.class文件。
⭐️第三步:类加载器如果在硬盘上找不到对应的字节码文件,会报找不到或无法加载主类
类加载器如果在硬盘上找到了对应的字节码文件,类加载器会将该字节码
文件装载到JVM当中,JVM启动“解释器”将字节码解释为“1010...”这种
二进制码,操作系统执行二进制码和硬件交互。
❤️3、CLASSPATH是给“类加载器”指路的
⭐️问题:
默认情况下,类加载器去硬盘上找“字节码”文件的时候,会从当前路径下找。
那么能不能给类加载器指定一个路径,让类加载器去指定的路径下加载字节码文件?
答案:是可以的。但是我们需要设置一个环境变量,叫做:classpath
⭐️classpath是一个环境变量,是给“类加载器”指路的
classpath环境变量不属于windows操作系统,classpath环境变量隶属于java
⭐️注意:变量名不能随意写:大小写无所谓,但必须叫做:classpath
⭐️特点:配置了classpath=D:\course之后,类加载器只会去D:\course目录下找“xxx.class”
文件不再从当前路径下找了。这就很多此一举!
⭐️结论:到目前为止:classpath环境变量不需要配置。
⭐️但一定要理解classpath环境变量的作用?
(1)是给类加载器指路的。
(2)在没有配置环境变量classpath的时候,默认从当前路径下加载。
(3)如果配置了环境变量classpath的话,就只能从指定的路径下加载了。
⭐️在 java 开发中有很多第三方的类库需要在我们 的项目中引入,等需要引入其它类库的时候,我们就需要将这些类库的路径配置到 classpath当中。
❤️最终结论:Path、JAVA_HOME、CLASSPATH,这3个环境变量目前Path需要配置,
后面两个暂时不需要配置。最主要的是我们要了解每个环境变量的代表意义,而不是上来就胡乱进行配置!
🥅程序的剖析
❤️三种注释方法
⭐️// 单行注释
⭐️ /*
多行注释
*/
⭐️ /**
* javadoc注释:注释信息可以自动被javadoc.exe命令解析提取并生成到帮助文档当中。
*/
public class HelloWorld{//声明定义一个公开的类,起个名字叫HelloWorld //在java中任何有效的代码必须写到“类体”当中,最外层必须是一个类的定义。 //public表示公开的,class表示定义一个类,HelloWorld是一个类名。类名后面必须是 一对大括号,这一对大括号被称为“类体” //1、下面是类体 public static void main(String[] args){ //这是一个入口方法。这里args是变量,可以更改 2、下面方法体 //整个这一块的代码被称为:main方法/主方法(程序的入口) //JVM在执行程序的时候,会主动去找这样一个方法。没有这个规格的方法,程序是无法执行的。 //注意:方法必须放到“类体”中,不能放到“类体”外面。 //任何一个程序都要有一个入口,没有入口进不来,无法执行。 //方法体:方法体由一行一行的“java语句”构成 //非常非常重要的是:方法体中的代码遵循自上而下的顺序依次逐行执行。 System.out.println("Hello World"); System.out.println("你好 世界"); // System.out.println();这行代码的作用是向控制台输出一句话。 } }
🏀5.public class 和 class的区别
public class Class{ public static void main(String[] args){ System.out.println("Test1"); } } class A{ public static void main(String[] args){ System.out.println("Test2"); } } class B{ public static void main(String[] args){ System.out.println("Test3"); } } class C{ public static void main(String[] args){ System.out.println("Test4"); } }
❤️能正常运行,Class.class、A.class、B.class、C.class都能生成!
⭐️第一个结论:
一个java源文件中可以定义多个class;并且会生成多个.class字节码文件。
⭐️第二个结论:
public的类不是必须的。可以没有。就算只有class也能正常运行。
⭐️第三个结论:
在源文件中只要有一个class的定义,那么必然会对应生成一个class文件。
⭐️第四个结论:
public的类可以没有,但如果有的话,public修饰的类名必须和源文件名保持一致。
并且public的类有也只能有1个。
总结:我们想要进入那个入口,直接使用java+类名就可以,比如上面的代码:java Class、java A、java B、java C;这只是测试,一般一个软件的执行入口是一个。不会出现多个的!
❤️JDK 常用的基本组件包括:javac(编译器)、java(运行 java 程序)、javadoc(提取 java程序的注释信息并生成帮助文档)、jar(打 jar 包)、jdb(查错工具)、javap(反编译器)、jconsole(系统调试和内存监控工具)等。有一些组件后面会慢慢讲到!
🏀6.简单习题练习
❤️第一题:编写 Java 程序,输出学生的基本信息,输出结果如下图所示:
public class Stu{ public static void main(String[] args){ System.out.println("学号:123456"); System.out.println("姓名:张三"); System.out.println("生日:2001年9月14"); System.out.println("家庭地址:安徽省阜阳市"); } }
❤️第二题:编写 Java 程序,输出京东商城商品列表信息,输出结果如下图所示:
public class JingDong{ public static void main(String[] args){ System.out.println("---------------------------------------"); System.out.println("|手机商品列表"); System.out.println("---------------------------------------"); System.out.println("|商品编号 |商品名称 |单价(元)"); System.out.println("---------------------------------------"); System.out.println("|1309203929|荣耀10青春版 |1299.00 |"); System.out.println("---------------------------------------"); System.out.println("|1309203920|红米Redmi Note7 |1199.00 |"); System.out.println("---------------------------------------"); System.out.println("|1309203922|HUAWEI P30 Pro |1299.00 |"); System.out.println("---------------------------------------"); } }
结束语
今天的分享就到这里,想要提升编程思维的,快快去注册牛客网开始刷题吧!各种大厂面试真题在等你哦!
💬刷题神器,从基础到大厂面试题👉点击跳转刷题网站