Alibaba java 技术图谱

Posted by Mannix on January 8, 2022

Alibaba Java 技术图谱


Java新手入门

环境准备

JDK的选型、安装与配置

https://developer.aliyun.com/learning/course/52

https://developer.aliyun.com/learning/course/52/detail/1021

JAVA 抽象层
  1. JVM(JAVA 虚拟机)

JVM 有很多组件,最开始用户的代码是通过 BAD CODE 写成,然后被 CLASS LOADER 加载,加载完之后就是 JVM 可以识别的内部数据结构。

BAD CODE 可以被执行,也定义了一些数据的类型。

下面是 JAVA 的一些执行引擎。这些引擎通过 ATM 接口和最底下的操作系统进行交互。

img

  1. JRE(JAVA 的执行环境)

JRE 和 JVM 几乎是一体的,但是 JRE 在组织上包括一些基础的类库,比如 java.net可以保护网络,java.io 可以保护文件,j.u.c 可以帮助构建并发的应用程序,这也是JAVA 流行的重要原因。

img

  1. JDK(开发工具包)

各种语言都有相应的开发工具包,JDK 就是 JAVA 的开发工具包,里面包含了开发工具。

如果需要开发 JAVA 程序,则需要开发包里面拥有 JAVA 的编译器。

img

历史上的众多 JAVA 实现

历史上有众多 JDK,JAVA 定义了语言规范,使得业界百花齐放,只要遵循这个规范,那就是一个 JAVA 虚拟机。

历史上出现过许多 JAVA 实现,比如 1996 年,SUN 公司提供了 Classic VM,不久后,SUN 公司在 1997 年推出了 Exact VM,特点是效率更高。

之后在 1999 年,SUN 公司收购了 Hotspot 虚拟机,是当时世界上最好的虚拟机,在 1999 年,取代了 Sun 的 Classic VM 虚拟机,成为了默认的 JAVA 虚拟机。之后又出现了 JRockit 和 IBM J9 。但是最终,Hotspot 称为 JAVA 默认的虚拟机。

img

“正统” Open JDK

Hotspot 是 OpenJDK 里面默认的 JAVA 虚拟机实现。OpenJDK 是由 JCP 这个组织去规划它的路线,进而实现它。

在 OpenJDK 基础上加上 Oracle 特性就是可以在 Oracle 官网上下载下来的 Oracle JDK。

然后第三方厂商也会基于 OpenJDK 去构建自己的构造,比如自己的发行版,例如亚马逊的 Corretto,Azul 的 Zulu,阿里巴巴也提供了 JAVA 发行版,在 OpenJDK的基础上加上阿里巴巴云原生特性,形成了阿里巴巴的 Dragonwell。

img

Oracle JDK 生命周期

使用 Oraacle 需要注意很多事情。Oracle JDK 有一个生命周期的限制。

在 Oracle JDK 8U212 这个版本开始,它的授权形式从 Oracle Binary Code License 变成了 Oracle Technology Network License。

简单来说,在生长环境使用 Oracle JDK 是要被收费的。下图描绘了 JDK 的生命周期形式。

img

红色长条表示 Oracle JDK 的生命周期支持,看蓝色长条表示 Open JDK 的生命周期支持。

对于普通用户来说,需要选择 Open JDK 的发行版,而不是去使用商业版的 Oracle JDK。

AdoptOpenJDK:JDK 发行的事实标准

目前,整个业界标准是 AdoptOpenJDK 去主导 Open JDK 的发行,因为 Oracle 不做这个发行,自然需要一个第三方组织去发行 Open JDK。

其中成员有 Amazon Corretto、IBM OpenJ9、SAP Machine、Alibaba Dragonwell。

AdoptOpenJDK 影响是非常大的,比如在 Spring 的官网上下载 JDK 的话,它会首先推荐去下载一个 AdoptOpenJDK。

下图是官网上长期的一个测试。

img

JDK 的质量保证

深挖一下测试是如何进行的,从源码构建出 JDK 的 Release image,它就是平时使用的 JAVA 命令。然后 image 需要通过 JTreg 测试,通过 TCK 的认证,只有经过完整测试之后,才是一个完整的 AdoptOpenJDK 的发行版。

JDK 选型小结
  1. 优先选择 OpenJDK
  2. Oracle 不再免费提供最新的 OpenJDK
  3. AdoptOpenJDK 下的 Dragonwell 是一个好的替代品
Java 运行环境的配置
  1. 下载 OpenJDK 发行版

Dragonwell

Alibaba Dragonwell 是一款免费的, 生产就绪型Open JDK 发行版,提供长期支持,包括性能增强和安全修复。阿里巴巴拥有最丰富的Java应用场景,覆盖电商,金融,物流等众多领域,世界上最大的Java用户之一。Alibaba Dragonwell作为Java应用的基石,支撑了阿里经济体内所有的Java业务。

https://dragonwell-jdk.io/

https://github.com/alibaba/dragonwell8

https://github.com/alibaba/dragonwell8/releases

Alibaba_Dragonwell_8.9.10

https://ghproxy.com/https://github.com/alibaba/dragonwell8/releases/download/dragonwell-8.9.10_jdk8u312-ga/Alibaba_Dragonwell_8.9.10_x64_linux.tar.gz

https://ghproxy.com/https://github.com/alibaba/dragonwell8/releases/download/dragonwell-8.9.10_jdk8u312-ga/Alibaba_Dragonwell_8.9.10_x64_windows.zip
https://dragonwell-jdk.io/

https://github.com/alibaba/dragonwell11

https://github.com/alibaba/dragonwell11/releases

Alibaba_Dragonwell_11.0.13.9

https://ghproxy.com/https://github.com/alibaba/dragonwell11/releases/download/dragonwell-11.0.13.9_jdk-11.0.13-ga/Alibaba_Dragonwell_11.0.13.9_x64_linux.tar.gz

https://ghproxy.com/https://github.com/alibaba/dragonwell11/releases/download/dragonwell-11.0.13.9_jdk-11.0.13-ga/Alibaba_Dragonwell_11.0.13.9_x64_windows.zip
https://dragonwell-jdk.io/

https://github.com/alibaba/dragonwell17

https://github.com/alibaba/dragonwell17/releases

Alibaba_Dragonwell_jdk-17.0.1.0.1+12

https://ghproxy.com/https://github.com/alibaba/dragonwell17/releases/download/dragonwell-17.0.1.0.1%2B12_jdk-17.0.1-ga/Alibaba_Dragonwell_17.0.1.0.1+12_x64_linux.tar.gz

https://ghproxy.com/https://github.com/alibaba/dragonwell17/releases/download/dragonwell-17.0.1.0.1%2B12_jdk-17.0.1-ga/Alibaba_Dragonwell_17.0.1.0.1+12_x86_windows.zip
http://openjdk.java.net/

https://jdk.java.net/17/

https://www.oracle.com/java/technologies/downloads/

img

  1. 解压安装

img

  1. 配置环境

img

  1. HelloWorld

img

下载
wget https://ghproxy.com/https://github.com/alibaba/dragonwell8/releases/download/dragonwell-8.9.10_jdk8u312-ga/Alibaba_Dragonwell_8.9.10_x64_linux.tar.gz

解压
tar xf Alibaba_Dragonwell_8.9.10_x64_linux.tar.gz -C /opt

配置
cat >> ~/.bashrc << EOF
export JAVA_HOME=/opt/jdk8u312-b01
export PATH=$PATH:$JAVA_HOME/bin
EOF

加载
source ~/.bashrc

验证
java -version

image-20220108230251892

[root@VM-8-12-centos /]# java -version
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (Alibaba Dragonwell 8.9.10) (build 1.8.0_312-b01)
OpenJDK 64-Bit Server VM (Alibaba Dragonwell 8.9.10) (build 25.312-b01, mixed mode)
 SSH  Connecting to 106.14.12.26
 SSH  Host key fingerprint:
 SSH   SHA256  4171fbe83b05ac0a3b9d9431f6e8f550c20521a2bb5f85145ed14379917278f1 
 SSH  Trying saved password
Last login: Sat Jan  8 23:06:03 2022 from 118.31.243.252

Welcome to Alibaba Cloud Elastic Compute Service !

[root@iZuf6er6cdez8ret8nz3bhZ ~]# wget https://ghproxy.com/https://github.com/alibaba/dragonwell8/releases/download/dragonwell-8.9.10_jdk8u312-ga/Alibaba_Dragonwell_8.9.10_x64_linux.tar.gz
--2022-01-08 23:08:16--  https://ghproxy.com/https://github.com/alibaba/dragonwell8/releases/download/dragonwell-8.9.10_jdk8u312-ga/Alibaba_Dragonwell_8.9.10_x64_linux.tar.gz
Resolving ghproxy.com (ghproxy.com)... 152.69.224.254
Connecting to ghproxy.com (ghproxy.com)|152.69.224.254|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 103337724 (99M) [application/octet-stream]
Saving to: ‘Alibaba_Dragonwell_8.9.10_x64_linux.tar.gz’

100%[============================================================================================================================================================>] 103,337,724 1007KB/s   in 69s    

2022-01-08 23:09:26 (1.43 MB/s) - ‘Alibaba_Dragonwell_8.9.10_x64_linux.tar.gz’ saved [103337724/103337724]

[root@iZuf6er6cdez8ret8nz3bhZ ~]# tar xf Alibaba_Dragonwell_8.9.10_x64_linux.tar.gz -C /opt
[root@iZuf6er6cdez8ret8nz3bhZ ~]# cat >> ~/.bashrc
JAVA_HOME=/opt/jdk8u312-b01
PATH=$PATH:$JAVA_HOME/bin
^C
[root@iZuf6er6cdez8ret8nz3bhZ ~]# source ~/.bashrc
[root@iZuf6er6cdez8ret8nz3bhZ ~]# java -version
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (Alibaba Dragonwell 8.9.10) (build 1.8.0_312-b01)
OpenJDK 64-Bit Server VM (Alibaba Dragonwell 8.9.10) (build 25.312-b01, mixed mode)

image-20220108231113774

使用Dragonwell运行Hello World程序
  1. 执行以下命令编写Hello World源代码文件。
cat > Hello.java <<EOF
public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
EOF

image-20220108232658166

  1. 执行以下命令编译源程序。
javac Hello.java
  1. 执行以下命令运行程序。
java Hello
  1. 执行以下命令查看程序的字节码文件。
javap -c Hello

image-20220108232946858

Java语法基础

Java编程入门

认识 Java(Java 发展简介)

Java 的具体内容

Java 是现在最流行的编程的语言之一,并且自身拥有庞大且完善的生态系统,可以实现你的任何需求(但不可能一门语言,实现的功能过多,所以,有些时候 Java 不擅长的部分会被其他的语言所顶替)。也就是说 在当前情况中 java 是整个编程的主力军,但是同一个正常来讲 它有它擅长和不擅长的地方,不擅长的地方, 就是慢慢发展之后 会寻求其他替代品。擅长的地方正在不断的应用,在国内而言,之所以 Java 使用广泛,更多的主要原因在于,有许多的大户都在使用 Java 实现其各自的核心业务。

大家所熟悉的一些大型网络公司,电商公司,基本上能看见的东西都是在后台通过Java 看见的,不过,近几年 Java 的发展也在不断地受到一些挑战,包括一些版权的争执等等。但这些东西跟我们大家使用者是没有关系的!有些系统是不可能轻易换掉的。

Java 编程语言介绍

Java 是由 SUN 公司开发的一套编程语言,其前身并不是 Java。

在 1991 年的时候,当时有一个 GREEN 项目,这个项目的核心功能在于使用 EMail控制家电产品的运行(智能家居这个项目就是当初GREEN项目想达到的目的)。在80 年代 Email 流行的时候,当时可以发送 Email 是一件很牛的事情。

但是遗憾的是,现在,基本不发邮件了,邮箱里停留的更多是一些广告和垃圾信息,可能永远都不会打开,但是前几年,邮箱里出现一个 Email,我们会觉得是个特别幸福的事。好莱坞有部电影叫《电子情书》有时间可以看一看,一个很文艺的片子,就是现实中是两个年轻男女,在网络中聊得特别好,互相发下信,一见面就认识了。所以说,这就是当年 Email 很火的原因。

最初 SUN 公 司打算竞争此项目,但是后来考虑到了 C++ 的复杂性。所以利用C++ 开发出了一套 OAK(橡树)平台,并且利用此平台进行项目的竞标,不过遗憾的是,这个平台的竞标结果失败了,一个项目竞标失败,可想产品也就没什么利润了。但是这个时候,世界上有个最早的软件公司诞生了,创造了第一个技术最短上市的神话,就是网景。(第一家依靠技术上市的公司)受到了当时最好的浏览器的启发,推出了一个 Hotjava 的浏览器,那么后来在 1995 年 5 月 23 日的时候正式推出了 Java 编程语言,同时推出了 JDK1.0 的开发包,(1996 年的时候才开始可以提供陆续下载使用,到 1997 年传到中国)。1996 年 到 1997 的时候,才是 java 出现在报纸上比较高的频率。当时我们的信息都是通过电脑报获取的。最早还有很多杂志。

后来之所以不再用 OAK 用 Java 的主要原因在于 OAK 不能在申请版权,而我们Java 是可以的。

SUN 公司的由来

Java 是由 SUN 公司开发的一套编程语言,那么 SUN 公司是一家从事硬件开发的技术性公司,SUN 最 早的代表性产品:小型机(被广泛的应用在了 amazon 上)。亚马逊现在也是非常火的,最初在国外是个电商,它除了提供电子商务产品之外,还出了很多技术性的图书,亚马逊在最初的时候,技术非常牛,也准备了很多经典图书。再往后,亚马逊又开始涉及到了云服务上,云服务在国外是以亚马逊为主。但是国内基本上很少见到亚马逊服务。能见到更多的情况下也只是个阿里云,京东云等。

最初的 SUN 公司 全称(Stanford University NetWork)90 年代末的时候有一本电子商务书将 SUN 公司翻译成太阳公司。为什么叫太阳公司,是因为翻译图书有问题。说道电子商务,最初电子商务是由 IBM 提出来的,第一代电商已经见不到了,比如,京东,卓越。当当。卓越现在已经变成了亚马逊。在后来才有了今天的淘宝。后来,由于网络经济的发展问题,(任何的经济模式都会出现瓶颈)但是对于 90年代末-2000 年初的互联网低潮而言,这就是一个严重的伤害。当时整个互联网的开发,待遇是非常高的。虽然当时是个低潮,但是也创造出了很多神话,比如汤姆网,汤姆网是当时李嘉诚最早干的一个网站,但是由于涉及的业务过多,没有集中力量,慢慢的就颓废了。在国内,最著名的问题是,新浪和搜狐,赞美上市失败。就因为新浪和搜狐的失败很多人认为互联网并不是一个所谓的金蛋。它可能来讲是需要我们重新认识的一个过程。而同时也正赶上 8848 衰落的时候,8848 是当时最早的中国互联网的第一颗金蛋。而 SUN 公司经历了这么一段发展之后并没有恢复往日的经济实力。终于在后来被 oracle 公司所收购,但是 Oracle 公司收购前最希望收购 SUN 的实际上是 IBM。

IBM 当年软件产品线上的技术基础就是 Java 语言(SUN 并没有通过 JAVA 赚多少钱,但真正使用 Java 赚到钱的只有 IBM,后来还有依靠版权欺诈的 Oracle)所以从发展历史来讲,Java也是挺坎坷的。但是不管这些公司如何得折腾,有一点已经达成了共识,Java 依然是一个稳定的、可靠的编程语言,可以承担大型服务器的程序开发任务。而从我们的最初年代到现在 Java 语言也出现了一些技术的不同发展。

Java 的开发形式

Java标准开发(J2SE、JAVA SE):提供的是底层的支持,实现了桌面程序的开发,主要就是单机程序,但是这个单机程序现在为止,实际上市场的份额并不高

Java嵌入式开发(J2ME、JAVA ME)SUN 公司最早的时候就是想做嵌入式开发,但是这个嵌入式的发展被当年的 Nokia 给折腾够了,后来基本上就被 Android所替代了,但是再后来由于 Oracle 和 Google 的矛盾,导致 Android 的发展也出现了一个瓶颈,后来 Google 推出了自己的专属的编程语言来进行 Android 的开发(Kotlin)

Java 企业开发(J2EE、JAVA EE)主要是进行企业平台的搭建,现在已经主要的开发是互联网平台。那么互联网平台对于JAVA的要求是越来越高,因为更多的情况下要考虑大用户访问的处理能力,所以今天为止我们再见到 Java 的这个过程基本上已经可以确定一点就是它已经不像最初我们开发那样只是个单机版程序。

Java语言特点

Java之所以可以得到持续的发展力以及良好的生态系统,这完全取决于Java的技术特征。

Java的开发技术

Java的开发技术是一个行业内通用的技术实现标准;

Java本身也算是一个半开源的产品,所以很多的厂商得以解除Java的底层,这样使得Java 开发的更加透明;并且Java是一门面向对象的编程语言:这样使得Java语言语法结构更加方便开发者接受,这些面向对象的设计思想还在不断进行着扩充(不同的JDK版本);

Java同行业内的优势

Java提供有方便的内存回收处理机制:像一些编程语言里面需要明确的手工进行对象的回收与释放,否则程序将无法正常提供支持,但是Java可以提供自动内存回收操作,这样处理会更加方便一些(这里面牵扯到一些优化方面的问题);同时避免了复杂的指针问题,而是用更加简单的引用来代替指针:指针虽然是一种高效的内存处理模式,但是其需要较强的逻辑分析,而Java在设计的时候充分考虑到了这一点,所以开发者直接利用引用就可以简化指针的处理,而引用也是在所有处理过程之中,最为麻烦最难理解的部分。

Java支持多线编程

Java是为数不多支持多线程编程的开发语言,这样就可以使得单位时间内,处理的性能得到提升(性能的提升并不是绝对的),多线程也是Java开发之中最难以理解的部分,而正确的多线程处理,才是处理问题的核心所在;其次Java提供有高效的网络处理能力,可以基于NIO实现更加高效的数据传输处理,Java具有良好的可移植性,这样就可以提升一个程序的适用范围,而且Java语言足够简单。

Java的可移植性

Java的可移植性

Java语言之中最大的特点在于其可移植性的支持,所谓的可移植性指的是同一个程序可以在不同的操作系统之间任意的进行部署,这样就减少了开发的难度在Java里面如果想要实现可移植性的控制,那么主要是依靠的是JVM(Java的虚拟机)

Java虚拟机(Java Virtual Machine)

Java虚拟机是一个由软件或硬件模拟出来的计算机,所有的程序只要有Java虚拟机的支持,就可以实现程序的执行,并且不同的操作系统上会有不同版本的JVM存在,这样就可以实现移植性。

计算机高级编程语言类型:编译型 解释型Java语言程序需要先编译形成字节码文件,而后在JVM进行解释文件,解释所有Java程序的解释都要放在虚拟机上处理,Java虚拟机(JVM)是用来读取并处理经编译过的与平台无关的字节码class文件。

Java编译器针对Java虚拟机产生的class文件,因此是独立于平台的,Java解释器负责将Java虚拟机的代码在特定的平台上运行。

JVM应用程序运行机制

所有*.java的源代码程序最终都是需要经过编译后才可以使用的,但是编译造成的程序代码并不是绑定在某个具体操作系统上的程序,而是一种通用性的程序,而这种通用性的程序就是JVM所能够识别的代码。

所有的程序并不是直接运行在操作系统上,而是通过JVM执行,这样一来肯定要比直接操作在系统上执行的程序的处理速度要慢,先期的确是一个问题,但是后来由于硬件技术的飞跃发现这些问题已经可以忽略了,但是目前依然会存在有JVM调优问题。

JDK简介

JDK特性

Java语言属于编译型与解释型的开发语言,对于Java语言,如果要想进行行开发,就一定要进行JDK的安装与配置,而JDK要想获取则需要通过官方网站获得,并且也需要在本机上进行配置。

主要的特性是提供了Lambda表达式

JDK发展历程

最早的时候JDK都是有SUN公司提供的(www.sun.com),但是后来SUN公司被Oracle公司收购,之后如果还要获得则就必须登陆Oracle官方网站(www.Oracle.com),

对于JDK而言,其本身也有一段自己的发展历史,主要有如下的几个标志性的版本:

【1995年05月23】,JDK1.0的开发包发布,同时在1996年正式提供下载,标志着Java的诞生;

【1998年1月04】,JDK1.2版本推出,而后Java正式更名为Java2(只是Java的升级版本);

【2005年05月23】,推出了JDK1.5版本,同时这个版本也是带来新特性以及开发支持更多的标志性的历史版本,可以说这一版本直接决定了Java后续十年的技术核心;

【2014年】 Java提供了JDK1.8版本,并且支持有Lambda表达式,可以使用函数编程;

【2017年 】Java提供了JDK1.9版本,进一步提升JDK1.8的稳定性;

【2018年】Java提供了JDK1.10版本,是属于JDK1.9的稳定版本;

(但是需要注意对于JDK1.8 、JDK1.9、JDK1.10三个版本做一个特别说明:如果要进行实际项目的生产环境部署,现阶段还行该以JDK1.8为主;JDK1.9和JDK1.10的区别不大,也就是说不管是使用JDK1.9或者JDK1.10效果是类似的)。

JDK下载方式

以JDK1.10为例,下载时会有下载环境项,能看到JRE选项,那么JRE指的是Java运行时的环境,就是说只提供程序的解释功能,不提供程序的开发功能,当本机已经配置好了JDK之后会自动进行JRE的更新处理。

下载JDK需要先接受下载协议,以后才可以选择版本下载,在计算机上实际上只有三类操作系统:Windows操作系统、UNIX操作系统、类UNIX操作系统(Linux、MacOS),根据计算机的操作系统选择下载开发包。

JDK的安装与配置

JDK的安装

首先当JDK下载完成之后由于其本身提供的是一个windows程序的安装结构,所以可以直接双击打开进行安装,选择安装的硬盘,

在JDK之中默认支持JRE,所以对于JRE就可以在安装JDK时同时进行配置。

JDK配置

安装完成以后,需要进行JDK的配置处理,在JDK里面所有可执行程序的路径为在安装时所选择的硬盘(例:D:\java\jdk-10\bin),在配置时主要用的是“javac.exe”和“Java.exe”的两个指令,

但是这两个命令并不属于windows本身,如果想在命令行里面进行使用,就必须在windows 的系统环境之中进行可执行程序的路径配置:

①右键【计算机】

②选择【属性】

③【高级系统设置】

④【环境变量】

⑤【系统产量】里面找到【Path】之后选择编辑,

然后把需要用到的JDK的命令拖到【系统产量】上来。

如果此时的命令行为方式已经打开了,那么将无法进行新的环境属性的读取,必须重新启动命令行方式之后才可以加载新的环境属性配置(加载Path路径)。如果在测试的时候能现实当前路径的话那么就说明JDK的程序已经安装成功了

ps:如果以后执行多个路径,那么那个路径中间需要用“分号”来进行分割。

安装成功了以后就可以进行正常代码编写

java编程起步

几乎所有语言的第一个程序都是“Hello World”,因为最初C语言出现的第一个程序编写的就是”你好,世界”,如果要定义Java程序,要通过记事本来进行编写,所有Java程序的后缀都是*.java程序,建立一个目录保存所有程序源代码,建立一个“Hello.java”的源程序。

范例:定义第一个程序代码
public class Hello {
    public static void main(String args[]) {
        System.out.println("Hello World !");
    }
}

Java程序是需要经过两次处理后才可以正常执行的: .

  • 对源代码程序进行编译:javac Hello.java,会出现有一个 Hello.class.的字节码文件
  • 利用JVM进行编译,编译出一套与平台无关的字节码文件(*.class );
  • 在JVM上进行程序的解释执行: java Hello.
  • 解释的就是字节码文件,字节码文件的后缀是不需要编写的;

为了更加方便的理解java程序的主要结构,下面针对于第一个程序进行完整的解释。

在java程序开发之中最基础的单元是类,所有的程序都必须封装在类中执行,而类的基本定义语法如下:

[public] class 类名称{}

在本程序之中定义的类名称为“Hello”,而类的定义有两种形式:。

  • “public class类名称{}” :类名称必须与文件名称保持一致,一个*.java_文件里面只允许有一个public class定义;
  • “class类名称{}”:类名称可以与文件名称不一致,但是编译后的.class名称是class定义的类名称,解析的时候要求解析的是生成的.class文件名称,在一个.java文件里面可以有多个class定义,并且编译之后会形成不同的.class文件;
  • 在以后进行项目开发的时候,很少会出现一个* .java源代码里面定义有多个class的情况,而对于以后的开发而言一个* .java文件里面就定义有一个public class类就够了。但是定义了多个文件会产生混乱,所以初期会在一个*.java文件中定义有多个类方便学习。

Java语言有着明确的命名要求,以后定义类名称的时候要求每一个单词的首字母必须大写,例如”HelloWorld“,才算标准。

主方法:主方法是所有的程序执行的起点,并且一定要定义在类之中

例:Java的主方法定义

[public] class 类名称 {
    public static void main(String[] args) {
        程序的代码由此开始执行
    }
}

java的主方法名称定义非常长,主方法所在的类都成为”主类“,所有的主类都将采用public class来定义。

屏幕打印(系统输出)可以直接在命令行方式下进行内容的显示,有两类语法形式:

  1. 输出之后追加换行:System.out.println(输出内容) ;
public class Hello {
    public static void main(String args[]) {
        System.out.println("Hello World!");
        System.out.println("Hello World!");
        System.out.println("Hello World!");
    }
}
  1. 输出之后不追加换行:System.out.print(输出内容)、ln(line 换行)
public class Hello {
    public static void main(String args[]) {
        System.out.print("He1lo");
        System.out.println(" Wor1d!");
        System.out.println("Hello World! ");
    }
}

JShell工具

具体内容:

Shell是脚本程序的含义,在很多的编程语言里面为了方便使用者进行代码的开发,都会有Shell交互式编程环境。有些时候可能只是为了一些简短的程序验证,但是在Java里面就必须编写很多的结构代码才可以实现,所以为了解决这样的困惑,供有jshell指令,直接运行。

除了可以直接在jshell命令之中进行程序的编写之外,也可以将一些内容直接交由一些文件来进行保存。

范例:定义一个程序文件:“d:/mldn.txt”。

希望可以直接在jshell里面直接执行本程序。

/open  d:/mldn.txt

本程序执行方法:

  1. 在程序后加上/open
  2. 找到d盘中的d:/mldn.txt,回车),执行结果如下:

用Jshell的好处:只需要编写核心结构的代码即可,减少了对于结构化的需求。

如果发现这个环境不想使用了,则可以在界面使用“/exit”进行交互式的界面退出。

CLASSPATH环境属性

CLASSPATH的概念

CLASSPATH如果要完整的进行解释需要好多知识,所以本次只是对CLASSPATH的概念做一个先期的介绍。

假设在d:\mldnjava目录下提供一个Hello.classde 字节码文件:

假设当前用户所在的目录为“d:\mldnjava”,这样的情况下直接使用java命令进行Hello.class字节码文件解释:

如果说现在脱离了这个目录,将当前目录修改了“C:\”(C盘目录下并没有Hello.class字节码文件),如果再次执行程序并解释,这个时候会出现以下错误提示信息:

image-20220109022655274

因为从1.6版本之后,都是多国语言版它会根据你当前的语言系统环境显示中文或英文。1.8版本只能看见前面一部分,1.9版本才可以看见后面一部分。

CLASSPATH的环境属性

出现ClassNotFoundException原因?

当前目录中没有字节码,那么现在的需求就是:可以在不用的目录中都执行

d:\mldnjava\Hello.class文件。所以在这样一个处理要求下只能够依靠CLASSPATH环境属性来完成。

范例:定义CLASSPATH环境属性。

SET CLASSPATH=d:\mldnjava
添加“.”环境变量

当设置了CLASSPATH之后,在java程序解释的时候会自动的通过CLASSPATH所设置的路径进行类的加载,所以可以得出一个结论:JVM解释程序的时候需要得到CLASSPATH的支持。但是有一个问题,发现默认情况下所有解释的类都是从当前所在的目录中加载的,所以可以得出一个结论CLASSPATH的默认设置韦当前所在目录加载类文件。很明显如果到出去设置CLASSPATH就会造成整个操作系统的混乱,那么从正常的角度来讲,对于CLASSPATH来说还是应该采用默认设置方式,所以如果这个时候要想只通过当前目录加载,则可以将CLASSPATH设置为“.”。

范例:从当前所在路径加载类

SET CLASSPATH=.

程序基本概念——注释

注释的意义

注释是程序开发中的一项重要组成技术。合理的注释可以使项目维护更加方便,但是很多公司由于技术管理问题,注释不尽合理,使得项目维护非常不便,在人员更换时期非常痛苦,对后续工作造成了很大的困扰。特别是新人在项目维护的时候,发现只有若干行代码,没有一个注释,给新人带来了巨大的工作压力。所以注释是一个非常重要的概念。

注释的本质

注释的本质在于,编辑器在进行程序编译的时候,如果发现有注释的内容,将不对此部分进行编译处理。即用来解释说明的文字分类。

注释的分类

Java中注释共有三类:

  1. 单行注释://,即双斜线之后到当前行结尾的内容被注释。
  2. 多行注释:/*……*/,则/* */之间的内容被注释掉,可以跨多行注释。
  3. 文档注释:/** …*/;(文档注释需要很多选项,一般建议通过开发工具控制,因为采取手写的方式较为麻烦)
举例

定义单行注释:新建程序后,输入单行注释标志符号,添加所要注释的内容。

定义多行注释:可在单行注释标志符号处删改,使用多行注释标志符号,添加所要注释的内容。

总结

使用什么类型的注释,依据个人实际情况来决定;如果使用开发工具开发,单行注释较为方便;对于一些重要的类或者方法,建议使用文档注释。

标识符与关键字

什么是标识符?

在任何一个程序之中实际上都是一个结构的整合体,在Java语言里面有不同的于不同的结构,例如:类、方法、变量结构等,那么对于不同的结构一定要有不同的说明。那么对于结构的说明实际上就是标识符,是有命名要求的,但是一般都要求有意义的单词所组成,同时对于标识符的组成在Java之中的定义如下:由字母、数字、下划线、$所组成,其中不能使用数字开头,不能使用Java中的保留字(关键字)。

最简单的定义形式:使用英文字母开头,例如Student_Name,StudentName,而且对于”$“一般都有特殊的含义,不建议出现在你自己所编写的代码上。

什么是关键字?

关键字是系统对于一些结构的描述处理,有着特殊的含义。例如public、class等就有特殊含义,这些就是关键字,不可以把它作为标识符使用。Java 中的关键字一共包含有如下的一些内容:

img

对于所有关键字的定义不要求去背,对于以上的关键字有一些简短的说明。

  • JDK 1.4的时候出现有assert 关键字,用于异常处理上;

  • JDK 1.5的时候出现有enum关键字,用于枚举定义上;

  • 未使用到的关键字:goto、const; .

  • 有一些属于特殊含义的单词,严格来讲不算是关键字:true、false、null。

Java数据类型简介

程序基本概念

程序是一套数字处理的游戏框架,在整个程序开发的过程之中,所达到的最终目的就是对一些数据的处理过程,既然要进行数据的处理,就一定需要提供各种类型的数据定义。

Java数据分类

在Java语言之中对于数据类型一共分为两类:

  1. 基本数据类型:描述的是一些具体的数字单元,例如:1、1.1;

可分为以下几类:

数值型:

  • 整型:byte、short、int、long; 默认值:0

  • 浮点型:float、double; 默认值:0.0

  • 布尔型:boolean; 默认值:false

  • 字符型:char; 默认值:’\u0000’

  1. 引用数据类型:牵扯到内存关系的使用;

重点有以下三种类型:

数组、类、接口。 默认值:null

真正复杂的部分就是引用数据类型,引用数据类型需要通过许多实例加以说明。而每一种数据类型都有默认值,其默认值如上。

而本次讨论的主要是基本数据类型,这里不牵扯到复杂的内存关系的匹配操作。每一种数据类型都有每一种类型保存的数据范围,如下图所示:

img

上图给出了数据的保存范围,其中记住int是比较有帮助的。如果保存数据,byte是比较小的,只有8位;可把short、int表示的数据范围记一下,而float、char表示的数据范围较大,可不记。

不同的类型保存有不同范围的数据,这里面实际上就牵扯到了数据类型的选择上,那么对于以上的数据类型划分,给出个人的一些使用参考原则:

  • 如果要是描述数字首选的一定是int(整数)、double(小数);

  • 如果要进行数据传输或者是进行文字编辑转换使用byte类型(二进制处理操作);
  • 处理中文的时候最方便的操作使用的是字符char来完成(可选概念);
  • 描述内存或文件大小、描述表的主键列(自动增长)可以使用long;

以上几种数据类型是经常考察的,而short和float相对以上几种数据类型基本上比较考察比较少。

整型数据类型

整形数据四种分类

整形数据类型一共有四种,按照保存的范围由小到大分别是:byte、short、int 、long ,在Java里面任何一个的整形常量(例:10 不会改变)其默认的类型都是int型(只要是整数就是int类型的数据)。

int的编译执行

范例:定位int型变量

img

范例:修改“x”内容

lydiuqirxcrbmyhssfmc

任何数据类型都有其可以保存的数据范围(正常使用下很少会出现超过此范围的数据)

范例:超过了处理范围

gmgcjauqktglhmkkqtjt

通过此时的执行结果可以发现这些数字在进行处理得时候如果超过了其最大的保存范围,那么将出现有循环的问题,而这些问题在Java中被称之为【数据溢出】,如果想解决这种溢出,就可以继续扩大使用范围,比int更大的范围是long。

long的编译执行

范例:解决数据溢出

img

在操作的时候预估数据范围,如果发展范围不够就使用更大

范围时ling型变量+int型常量=long型计算结果。

除了可以定义long型的变量之外,也可以直接在常量上进行处理,默认的整数常量都是int型,那么可以为他追加字母“L”或者直接使用“long”转换。

img

现在发现数据类型之间是可以转换的,即:范围小的数据类型可以自动转换为范围大的数据类型,如果反过来范围大的数据大的类型要转换为单位小的数据类型,那么就必须采用强制性的处理模式,同时还需要考虑可能带来的数据溢出。

范例:强制类型转换

img

所以程序支持有数据转换处理,但是如果不是必须的情况下不要做这种转换。

在进行整形处理得时候,需要特别注意byte类型,首先这个类型的范围是:-128~127之间,也就是说它保存的数据量很小。

定义byte变量

范例:定义byte变量

img

正常来讲在Java程序里面20这个数字应该是int型,但是在为byte赋值的时候并没有因为是int型而发生强制类型转换,这是因为Java对byte做了特殊处理,即:如果没超过byte范围的常量可以自动由int变成byte,如果超过了就必须强制转换。

范例:int强制转换为byte

img

由于现在200已经超过了byte的范围,所以产生了数据溢出的情况(只针对于常量)

img

虽然对于常量可以自动适配转换,但是如果对于变量则还是必须使用强制转处理。

浮点型数据

定义double变量

范例:

public class Hello {
    public static void main(String args[]) {
        //10.2是一个小数其对应的类型为double
        double x = 10.2;
        int y = 10;
        //double类型* int类型= double类型
        double result = x * y;
        System.out.println(result);
    }
}

总结:所有的数据类型进行自动转型的时候都是由小类型向大类型进行自动转化处理。默认类型为double,但是也可以定义位数相对较少的float变量,此时重新赋值的时候就必须要采用强制类型转换。

浮点型数据描述的是小数,而在Java里面任意一个数常量其对应的类型为double,所以在以后描述小数的时候都建议使用double来进行定义。

定义float变量

范例:

public class Hello {
    public static void main(String args[]) {
        float x = (float) 10.2;
        float y = 10.1F;
        System.out.println(x * y);  // float型
    }
}

总结:通过一系列的代码分析发现,整形是不包含有小数点的,而浮点型是包含有小数点的。

通过代码详细了解二者的区别

范例:观察一个程序

public class Hello {
    public static void main(String args[]) {
        int x = 10;
        int y = 4;
        System.out.println(x / y);
    }
}

总结:此时的计算结果为2,得到2的主要原因在于,整形是不保存小数点的,所以现在的计算结果为2.5 ,那么抛开小数点来看,最终的结果只是2。如果现在要想得到所需要的正确的计算,那么就需要进行转型处理。

强制类型转换

范例:

public class Hello {
    public static void main(String args[]) {
        int x = 10;
        int y = 4;
        System.out.println((double) x / y);
    }
}

总结:计算的时候一定要注意选择的数据类型,它将会直接决定小数点的问题,这一点至关重要。

字符型

定义一个字符型变量

字符型使用的是char进行定义的,在Java之中使用单引号定义的内容就是一个字符。于是以下将研究如何去使用字符,例如定义一个字符型变量。

范例:定义一个字符型变量

public class Hello {
    public static void main(String args[]) {
        char c = 'B';//一个字符变量
        System.out.println(c);
    }
}

现在程序直接输出一定是正常的字符B。

观察Char与int的关系

首先要明确在任何的编程语言之中,字符都可以与int进行互相转换,字符中所描述的内容可以通过int获取其内容对应的系统编码。最早的计算机搭造的只是010101,但是如果用01的数字(例如110 101 数字等)来描述,尽管简化了一些过程,但却很难理解的。

范例:观察char与int的关系

public class Hello {
    public static void main(String args[]) {
        char c = 'A';//一个字符变量.
        int num = c; //可以获得字符的编码
        System.out.println(num);
    }
}

代码编译执行之后,答案是65。

将小写字母变为大写字母

对于以上的程序获得了编码,这里面有几个范围需要注意:

  1. “大写字母范围”:’A’(65)~’Z’(90);A编译执行的结果是65,Z编译执行的结果是90。
  2. “小写字母范围”:’a’(97)~’z’(122);在程序中输入a编译执行的结果是97,z编译执行的结果是122。
  3. “数字范围”:’0’(48)~’9’(57);在程序中要注意0跟’0’不是一个概念,前者是整数字,后者是字符,而字符是有编码的。在以上程序中输入0,编译执行结果是48。输入9,编译执行的结果是57。所以字符零和零完全是两个概念,单引号括起来的内容就是字符的数据

通过编码范围可以发现大小写字母之间差了32个数字的长度,于是就可以实现大小写的转换处理。程序如下:

范例:将小写字母变为大写字母

public class Hello {
    public static void main(String args[]) {
        char c = 'x';//一个字符变量
        int num = c;//可以获得字符的编码
        num = num - 32;//让自己的内容减少32
        System.out.println((char) num);
    }
}

例如现在有小写字母x,想让他变成大写字母。就需要进行强制转型,将int变成字符。然后就做到了小写字母变成大写字母的转型。

保存中文数据

到此为止,所有的操作都与传统的c语言的方式是一样的,但是需要注意的是在java里面存在char的处理,char主要是进行中文的处理,所以Java中的char类型可以保存中文数据。

范例:保存中文数据

public class Hello {
    public static void main(String[] args) {
        char c = '仁'; //一个字符变量
        int num = c; //可以获取字符的编码
        System.out.println(num);
    }
}

例如在程序中输入仁(字符就只有一个字),观察是否能够运行且是否能够保存。编译执行到结果为20161。20161这个值已经很大了。所以Java中是允许保存有中文的,char最大的优势也就在于中文处理。之所以在java语言里面可以使用char进行中文数据的保存,是因为java使用的是unicode这种十六进制的编码,这种编码的主要特点是可以包括任意的文字内容,所以使得程序开发更加的简单。

最初的时候,如果看到一篇文章非常的长,那么一般需要通过切来换行,但是切文字的时候就比较繁琐。一个字母占一个字节,一个字符占两个字节,如果按照字节的概念,字母的切跟中文的切是不一样的。字母会切得非常完整,但如果是中文,就可能把非常的非切成两半,于是造成了断码。还要去判断是否是正常值,如果是正常值就可以切,不是正常值就要往前找。所以如果有了java这种字符描述16进制的方式,存放中文的时候就会更加方便,这就是unicode的主要作用。

所有的操作方法适合于各种数据操作,就因为它的编码是统一的,所以在描述中文的时候,要使用char来描述。

布尔型

String字符串

String字符串简介

在任何语言里面都没有提供所谓的字符串这种数据,但是从实际的使用上来讲各个编程语言为了方便程序的开发,也都会提供有字符串的相应描述。在Java里面使用的是String作为字符串的定义。

由于String类的存在较为特殊,所以其可以像普通变量那样采用直接赋值的方式进行字符串的定义,并且要求使用“""”进行字符串描述。

范例:定义一个字符串

public class Hello {
    public static void main(String[] args) {
        String str = "Hello World !"; //使用双引号进行描述
        System.out.println(str);
    }
}

在进行字符串变量使用的时候也可以使用“+”来进行字符串的连接处理。

范例:实现字符串的连接

public class Hello {
    public static void main(String[] args) {
        String str = "Hello"; //使用双引号进行描述
        str = str + " World"; //字符串连接
        str += " !!!"; //字符串连接
        System.out.println(str);
    }
}

但是需要考虑另外一点,此时对于“+”就有了两种描述:字符串的连接、数字的加法计算。那么下面来观察一个程序。

范例: 观察“+”的问题

public class Hello {
    public static void main(String args[]) {
        double x = 10.1;
        int y = 2;
        String str = "计算结果: " + x + y;
        System.out.println(str);
    }
}

在Java语言里面,数据范围大的数据类型与数据范围小的数据类型进行计算的时候,所有范围小的数据类型自动转型为范围大的数据类型,但是如果此时有String字符串了,则所有的类型无条件先变为String,如果有“+”表示的就是字符串连接。

在描述字符串的时候也可以使用转义字符进行一些处理,例如:TAB (\t)、”(\")、’(\')、换行、( \n)、(\\)。

范例:观察转义字符

img

这些字符是可以在学习的过程之中进行一些简单的格式化显示处。

运算符简介

具体内容:

概念:所有的程序开发都是一种数字的处理游戏,那么对于数字的处理,一定会有所谓的操作,而这些操作模式就称为运算。

例如:如果要进行加法运算肯定使用的“+”这样的运算符来完成,而对于运算符而言,也是存在有先后的关系,像小学学习四则运算,采用先乘除后加减的顺序来完成。

首先对于程序开发而言,里面会提供有大量的基础运算符,那么这些运算符也都会提供有各自的优先顺序,可是从正常的角度来讲,个人强烈不建议去记这些运算符优先级。

img

关键性的问题是,对于程序的开发而言,个人强烈不建议编写很复杂的计算。

范例:

如果项目代码里面按照这样的逻辑编写了代码,基本上没有人看懂,也容易出错。所以对于程序代码而言,实际上已经告别了复杂程序逻辑时代,更多情况下是希望大家去编写一些简单易懂的代码。

数字运算符

在Java数学运算提供了标准的支持,包括四则运算都是支持的。

四则运算

范例:

img

在进行变量计算的时候,编程语言一般也都会有简化的运算符(+=、*=、−=、÷=、%=)支持。

简化运算符

范例:

img

对于以上“num=num+20”在内存小的时代就不合适了,所以才提供有一系列的简化运算。

求模

范例:

img

编译执行得出的“1”。

在数学计算里面最头疼是“++”、“−−”,因为这两种运算符有两类使用方式:

①++变量、−−变量:先进行变量的自增或者自减,而后再进行数字的计算;

②变量++、变量−−:先使用变量进行计算,而后再进行自增或自减。

实现自增与自减

范例:

img

img

以上所有代码程序都是在当初内存量不大的情况下提供的处理方式,现在这种计算就变得非常繁琐了,尤其是在计算机硬件成本降低了的今天,这类操作如果不是必须的情况下,不建议这样使用。

所以数学计算这个运算关系里面就写简单的计算操作。

关系运算符

关系运算的主要特征:进行大小的比较处理。

包括:(>)、小于(<)、大于等于(>=)、小于等于(<=)、不等(!=)、相等(==)。所有的关系运算返回的判断结果都是布尔类型的数据;

范例:做一个大小关系的判断。

public class Hello {
    public static void main(String args[]) {
        int x = 10;
        int y = 20;
        boolean flag = x > y;  //false
        System.out.println(flag);
    }
}

进行关系判断的时候特别需要注意的就是相等的判断问题。在Java里面“=”表示的是赋值运算,而内容相同的比较是“==”。

范例:判断相等。

public class Hello {
    public static void main(String args[]) {
        int x = 10;
        int y = 10;
        boolean flag = x == y;  //true
        System.out.println(flag);
    }
}

进行关系运算的时候可以针对于所有的基本数据类型,例如:也可以直接使用字符来处理。

范例:在字符处理上使用关系运算

public class Hello {
    public static void main(String args[]) {
        char c = '建';
        boolean flag = 24314 == c; //true
        System.out.println(flag);
    }
}

数据类型之间提供有转型支持,所以在进行判断的时候字符会自动转为int而后进行数字的比较。

逻辑运算符

三目(赋值)运算符

进行程序开发的时候三目运算符使用的非常多,而且合理的利用三目运算可以避免一些大范围的程序编写。三目是一种所谓的赋值运算处理。它是需要设置一个逻辑关系的判断之后才可以进行的赋值操作,基本语法如下:

关系运算?关系满足时的内容:关系不满足时的内容

范例:判断两个数字的大小,将最大值保存

public class Hello {
    public static void main(String args[]) {
        int x = 10;
        int y = 20;
        // 判断x与y的大小关系来决定最终max变量内容
        int max = x > y ? x : y;
        System.out.println(max);
    }
}

对于程序开发,代码越少越好。两种方式,前者只用了一行,而后者用了多行。

三目运算本身也可以进行嵌套处理,也就是说在赋值语句位置上可以进一步编写三目运算。

范例:三目运算嵌套,将三个数字中的最大值保存下来

public class Hello {
    public static void main(String args[]) {
        int x = 10;
        int y = 20;
        int z = 15;
        int max = x > y ? (x > z ? x : z) : (y > z ? y : z);
        System.out.println(max);
    }
}

注意:虽然允许进行嵌套处理,但是程序的可读性变的很差,根据实际的情况确定是否使用。