亲爱的朋友们,今天我们来学Java。这个可能比你的年龄都要大的语言。听说,学会了它,咱们就能有【对象】了呢。并且在今后的日子里,每天都要【面向对象】,你们将一起沐浴着【春天】的阳光,脑子里充满了【idea】,你们会一起在【From】【To】之间来来回回,反反复复,直到产生一堆【垃圾】被自动回收。当然,也并不是所有的对象都会成为垃圾,偶尔也会有幸存者。它们将以胜利者的姿态,被冠以永久的光环,直到“世界毁灭”。
说道这里,也许你根本不知道我在说啥,甚至《少数人》觉得我在开车。但其实,我在《正经》说话。不信你就接着往下看,相信《很快》你就知道了。
什么是Java
我们要学java,究竟学的时什么。如何理解Java。我个人更愿意将其分为狭义上的理解和广义上的理解。
- 狭义:java是一门面向对象的高级的、解释型的编程语言。 所谓高级的,指的相对底层语言而言的层级上高级,不是高大上的意思。 所谓面向对象,是它的编程思想和语法。 所谓解释型,是它要先经过编译阶段,将源文件编译为字节码文件, 然后再由java虚拟机解释执行字节码文件。 所以,准确的说,它应该是 编译型语言( 源文件-》字节码 ) 和解释型语言( 字节码-》解释执行 )的混合体。
编译型:指的是,一次性把语言编译成机器语言。直接运行
解释型:指的是,解释一句,执行一句。
举一个网上常见的例子(个人觉得非常形象)。
奥巴马想看三体,但看到第三部的时候,看不了啦。于是,在线催更。。。。等别人把第三方部翻译完了,他再看。这就是编译型。
奥巴马想看三体,但是到第三部的时候,看不了啦。于是,雇了个翻译。。。坐在身边翻译一句,他看一句。这既是解释型。
奥巴马老婆想看三体,但是到第三部的时候,看不了啦。于是,奥巴马雇了个翻译。。。翻译把整本书翻译成英文后。奥巴马一句一句的读给她老婆听。这就是java。
通过上面的例子我们可以看出,奥巴马是个暖男。。。。
翻译就是-将源文件编译成字节码的过程。奥巴马就是虚拟机中的解释执行引擎,一句句的解释执行字节码文件
- 广义:广义上理解,奥巴马除了是......额不不不。。。Java除了是一门语言,更是一个完整的平台和生态。这其中,java语言是基础。额外还包括众多的类库和框架。而大部分人要学的,就是广义上的Java。掌握Java语法知识,也许你天赋异禀一周就搞定了。但是要想掌握Java完整的生态,它一定贯穿你整个职业生涯(当然,大概率,你也没必要完全做到这一点)。
Java概述
Java是一门面向对象设计语言(相对于面向过程而言,如C语言),于1995年诞生。可能你对1995年没啥概念。因为也许那一年你还没出生呢。那我们一起来看看哪一年还发生了其他什么大事件。
那一年。世界贸易组织刚刚成立
那一年,雅虎网站刚刚成立
那一年,发生了震惊世界的卢旺达惨案
那一年,邓丽君逝世
那一年,Windows 95正式发布
那一年......好,我们继续聊Java。此处省略十万字。
Java发展主要里程碑
-
1996年1月:JDK1.0正式对外发布
-
1999年6月:JDK分为三个版本发布:标准版SE,企业版EE,微型版ME
- J2SE:面向桌面应用程序(基本放弃)但学习Java语法知识一般用这个版本
- J2EE:企业级Web应用程序(主打,无人能出其右)
- J2ME:面向移动终端(早期诺基亚时代应用较多,随着智能机到来,基本被安卓和IOS替代了)
-
2009年4月:Sun公司被Oracle收购
-
2014年3月18日:JDK1.8发布。这是一次重大的版本更新,直到今天依然是一款经典版本,相对于早期版本主要更新了如下内容:
- lambda表达式的加入
- StreamAPI
- 静态方法等其他十大特性
-
目前JDK版本是16(2021年10月)
JDK5之前,版本命名一直是1.1,1.2,1.x的形式。从JDK1.5开始,命名改为了Java5,Java6....。但我们更喜欢称之为JDK1.x。所以,一般所说的Java8,也就是JDK1.8
截止到2021年,以更新到了java16。但目前用的最多的最稳定的版本依然是JDK1.8 (也就是java8)
编程语言排行榜
2021年8月数据
Java的第一印象
提到Java,对于80后90后而言,第一印象恐怕逃不开三个字“跨平台”。这是那个时期,JAVA最具代表性的特点之一。当然,放在今天,可能这个特点已经不是那么让人印象深刻了。但是,我还是想说一说,Java如何做到跨平台的。这对日后Java语言的学习甚至JVM的理解,是有一定帮助的。
如果你有一定的java开发或学习经验,那么,我问你一个问题,下面这张图对么?
感觉看似有那么一点道理,这不就是跨平台么?但似乎又不完全对的样子是吧。那么,到底是哪里不对呢,要不现在拿出纸和笔,自己画一画试试?
下面,我再给出一个相对完善的图。大家可以比较一下,然后想一想,这里面的差别代表着什么含义。
其实也不用想太多。我只是想通过这张图就是想告诉大家一件单纯的事情:千万别一听到JVM是虚拟机,就下意识的掉入到一个误区。以为自己电脑上安装了java环境,就是装了一个虚拟机,以后所有java应用都跑在这台虚拟机上。这个理解是有偏差的。
其实,每种操作系统,都有与之对应的JVM虚拟机。以适配底层差异。然后每一个java应用启动后。都会对应一个JVM虚拟机进程的。并不是所有应用共享一台“虚拟机”。
Java语言的特点
- 面向对象
- 强类型: 在编译期间就要指定数据是什么类型,不能搞错。
- 垃圾自动回收机制
- 解释型语言:先被编译为字节码形式,然后在解释器中逐句解释执行。
- 中立型语言: 编译后的字节码文件,能够屏蔽系统层,运行在任何能解释class字节码文件的虚拟机上。(JVM虚拟机并不一定是Oracle官方提供的。只要符合标准,能解释字节码文件,任何厂商都可以开发自己的Java虚拟机。甚至其他语言也可以把自己编译成可以运行在JVM虚拟机上的字节码形式。
Java语言运行机制
如何保证Java语言编写的程序,可以在不同的平台上运行呢,想必答案你已经知道了,那就是有Java虚拟机的存在,也就是JVM。如下图所示:
Java程序并不是直接运行在操作系统上的,而是运行在Java虚拟机上的。而不同的平台,分别有不同版本的Java虚拟机。JVM屏蔽了下层的系统环境,给APP一个统一的、标准的、模拟的系统平台。
Java程序编写执行流程
- 编写Java程序代码(.java文件)
- 编译器编译Java代码为JVM能够识别的字节码(.class文件)
- 不同平台的JVM解释字节码为机器指令,并运行程序
Java的运行开发环境
一提到Java,我们经常听到jvm、jre、jdk。它们三个到底是什么关系呢?下图直接说明了这一点。
JDK: Java Development Kit
JRE: Java Runtime Environment
JVM:Java Virtual Machine
Java环境搭建
接下来,就在咱们自己的电脑上,安装上java环境吧。
去oracle官网下载jdk,大体路径如下
Downloads - 》Java -》JDK -》找到相应的版本
当你找到了对应版本的jdk并下载下来后。咱们就开始安装吧。
MacOS
-
双击安装
-
找到安装目录
/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk -
配置环境变量 进入用户Home目录,
Bash环境执行:vi .bash_profile
或者Zsh环境,执行:vi .zshrc
写入以下内容:
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home
PATH=$JAVA_HOME/bin:$PATH:.
CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:. //可以不配
export JAVA_HOME
export PATH
export CLASSPATH //可以不配
⚠️理论上,JAVA_HOME你叫啥都行,因为你看你下面引用的就是$JAVA_HOME,只要这俩名字一样就可以了。但是,实际上最好还是叫JAVA_HOME。因为有些框架比如tomcat中、ES......,在依赖java的时候,配置文件中也是搜索的JAVA_HOME。为了保证统一性,所以我们一般都叫JAVA_HOME。其他框架配置环境变量也类似,大家还是用通用性的名字比较好,不要定义个性化的名字。
- 验证
$ source .bash_profile 或者 $source .zshrc
$ java -version
windows
- 下载并双击安装
x64版本的exe文件 - 在下一步的过程中,会让你选择安装的组件(开发工具、源代码、公共JRE)。选择前两个即可。
- 选择你规划好的安装目录(最好纯英文路径,避免出现乱码问题)
- 在cmd窗口下,进入安装目录/bin下,执行
java -version查看安装是否成功
- 依次右键【计算机】-》点击-》【属性】-》点击【高级系统设置】-》【高级】-》点击【环境变量】
在【系统变量】的PATH后面追加java安装目录,用;分隔。(win10系统下,一行一个路径,不用;分隔)
CentOS
-
下载安装包,然后解压(可选择解压到用户目录下或系统目录下,此处是用户目录,系统目录需要注意权限)
tar -zvxf jdk-8u231-linux-x64.tar.gz -C ~/app -
配置环境变量
将java环境变量配置到用户环境变量或系统环境变量中
export JAVA_HOME=/home/hadoop/app/jdk1.8.0_91 export PATH=$JAVA_HOME/bin:$PATH -
验证
$ java -version java version "1.8.0_91" Java(TM) SE Runtime Environment (build 1.8.0_91-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
CLASS_PATH 解释
classpath 其实是JVM中需要用到的一个变量,用来告诉JVM去哪里找.class文件(.java源文件编译后的字节码文件),所以,classpath的值,就是一堆目录路径的集合,jvm会依次到你指定的这些目录中,去找自己需要用到的.class文件,直到找到或者找不到。
比如这里一个项目的.class文件目录
一般设置classpath有两种方案:
- 在环境变量中设置(不推荐),因为这是一个全局的设置:
CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:. - 在启动JVM的时候设置,就是不同的app启动后,有自己的classpath。
java -classpath /xxx/xxx/xx:/xxx/xxx/xx:.
如果没有在任何地方设置classpath,那么默认的classpath就是当前目录.
有很多“如何设置classpath”的文章会告诉你把JVM自带的rt.jar放入classpath,但事实上,根本不需要告诉JVM如何去Java核心库查找class,JVM怎么可能笨到连自己的核心库在哪都不知道?
HelloWorld
说了那么多了,下面我们就一起来写一个java程序练练手吧
//此程序在MacOS环境中演示,在其他环境中一样
/*
1.编写java代码
2.javac HelloWorld.java 编译为字节码文件(java 源文件名)
3.java HelloWorld 运行HelloWorld Java程序(java 类名)
4.java HelloWorldSecond 运行HelloWorldSecond Java程序(java 类名)
*/
public class HelloWorld{
public static void main(String[] args){
System.out.println("Hello World!");
}
}
/*
一个源文件中,可以有多个平级类,编译后会生成多个class文件。但是只能有一个public修饰的Java平级类,而且只能加在和文件名同名的类前面。
*/
class HelloWorldSecond{
public static void main(String[] args){
System.out.println("Hello Second");
}
}
⚠️:进一步解释:
javac HelloWorld.java把源文件,编译为字节码文件,源文件中每个类,都会生成一个字节码文件,字节码文件名是 类名.class
java HelloWorld将HelloWorld.class字节码文件加载到JVM中成为Class类,并运行该类的主方法。所以,主方法一定要是static修饰的静态方法,不然没法用类直接调用。
java HelloWorldSecond同上
java XXX执行某个类时,java默认会在当前目录下查找主类。如果配置了CLASSPATH,则会去CLASSPATH所指定的目录去找。 找不到就会回到当今目录找
本篇文章结束,下一篇文章即将到达战场