概念

  • 计算机程序

    为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合

  • 计算机语言

    • 机器语言 0,1
    • 汇编语言 pop ,end 底层的语言
    • 高级语言 英文,数学表达式

Dos命令

  • (Disk Operating System:磁盘操作系统)
  • 打开dos窗口:Win+R ,输入CMD。
命令 说明
help 帮助
盘符: 切换盘符,如D:
dir/dir 路径 显示文件目录清单
/s 查看目录的文件和子目录
/p 分屏显示
dir /s/p 分屏显示所有
cd 改变目录
cd .. 返回上一级
cd \ 返回根目录
md 目录名 创建目录/创建文件夹
copy con 文件名.扩展名 创建并文件,输入内容后按ctrl+z键,然后再按回车保存。
type 文件名.扩展名 显示文件内容
copy 文件名.扩展名 目标路径 复制文件
ren 原文件名 新文件名 重命名
move 原文件名 目标路径 移动(剪切)
rd 目录名 删除空的目录
/S 除目录本身外,还将删除指定目录下的所有子目录和文件。用于删除目录树。
/Q 安静模式,带 /S 删除目录树时不要求确认
del 文件.扩展名 删除文件
cls 清屏
exit 退出

java 的发展史

  • 1996年,sun发布了JDK1.0
  • 2009年 ,甲骨文收购了Sun

高级语言分类

  • 编译型:速度快

    • 源代码–(编译器)—-> 机器码(针对特定的操作系统和CPU)
  • 解释型:慢但可以跨平台

    • 源代码–(解释器)—-> 解释执行
  • Java语言:编译解释型语言

    • 源代码–(编译器)–>字节码文件–(解释器)–>机器码
      比解释型快,还能跨平台

Java 语言的特点

  • 可移植性与平台无关的特性使Java程序可以方便地移植到网络上。(JVM不是跨平台的。)

  • 垃圾回收内存管理:自动回收,通常是内存满了才回收

Java语言概述

Java是如何实现跨平台

  • java virtual machine:就是我们常说的java虚拟机,它是整个java实现跨平台的最核心的部分,我们编写的Java源码,编译后会生成一种 .class 文件,称为字节码文件。Java虚拟机就是负责将字节码文件翻译成特定平台下的机器码然后运行。

  • 也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行

  • JVM也是一个软件,是用C/C++开发的,不同的平台有不同的版本。只要在不同平台上安装对应的JVM,就可以运行字节码文件,运行我们编写的Java程序。

  • 而这个过程中,我们编写的Java程序没有做任何改变,仅仅是通过JVM这一”中间层“,就能在不同平台上运行,真正实现了”一次编译,到处运行“的目的。

  • 所以,运行Java程序必须有JVM的支持,因为编译的结果不是机器码,必须要经过JVM的再次翻译才能执行。即使你将Java程序打包成可执行文件(例如 .exe),仍然需要JVM的支持。

JDK与JRE的区别

  • JDK是Java的开发工具,它不仅提供了Java程序运行所需的JRE,还提供了一系列的编译,运行等工具,如javac,java,javaw等。

    • 开发工具 + JRE + 类库
  • JRE只是Java程序的运行环境,它最核心的内容就是JVM(Java虚拟机)及核心类库。

    • JVM(java虚拟机) + 类库

jdk工具部分exe解释

  • jar.exe jar包
  • javadoc.exe 文档生成器
  • Java.exe 解释器
  • Javac.exe 编辑器

环境变量配置

  • 我的电脑 –> 环境配置
  • 环境变量的目的:在任何路径下都能识别java, javac命令
  • 需要配置JAVA_HOME,classpath ,path
    • path 环境变量 %JAVA_HOME%\bin;
    • JAVA_HOME 指定JDK的安装路径
    • classpath :在任何路径下都能找到.class文件 解释运行

JVM的内存空间

  • Heap 堆空间:分配对象 new Student()
  • Stack 栈空间:临时变量 Student stu
  • Code 代码区 :类的定义,静态资源 Student.class
1
2
3
4
5
6
7
Student stu = new Student(); //new 在内存的堆空间创建对象
stu.study(); //把对象的地址赋给stu引用变量

// 上例实现步骤:
a.JVM加载Student.class 到Code区
b.new Student()在堆空间分配空间并创建一个Student实例
c.将此实例的地址赋值给引用stu, 栈空间

Hello World

开发与运行Java程序过程

  • 用工具编辑源程序,也就是写代码,保存
  • 用Java编辑器工具javac.exe编译源程序文件,生成字节码.class文件
  • 用Java解释器工具Java.exe解释运行生成.class文件

编写第一个程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Hello{
public static void main(String[] args){
System.out.println("Hello World!");
}
}
运行:在Dos窗口下,cd 到JDk的安装路径下\bin目录
1.javac Hello.java
-->生成Hello.class
2.java Hello(类加载只能识别类名,不能带扩展名)
-->控制台输出Hello World!

出现的问题:
找不到或无法加载主类Hello:
java -classpath d:\data Hello
(Hello.class的路径)
注意:
1.java区分大小写
2.符号 英文半角
3.()[] {} 成对出现
4. 语句结束用分号;
5.每行写一句代码,代码有缩进。

转义序列

控制台打印输出

  • 输出语句:

    1
    2
    3
    4
    5
    6
    System.out.println("字符串");//输出后换行
    System.out.print("字符串"); //输出后不换行
    System.out.println("c:\a.txt");
    ---------- javac ----------
    Hello.java:3: 错误: 非法转义符
    System.out.println("c:\a.txt");
  • a:用97表示

    • 八进制转义:\000 - \7777
    • System.out.println("\141") //a
  • 十六进制转义:\u0000 - \uffff

    • System.out.println("\u0061") //a

转义字符

  • 区分,斜杠:/ 与 反斜杠:\ ,此处不可互换

    所有的转义字符和所对应的意义:

转义字符 意义 ASCII码值(十进制)
\b 退格(BS) ,将当前位置移到前一列 008
\f 换页(FF),将当前位置移到下页开头 012
\n 换行(LF) ,将当前位置移到下一行开头 010
\r 回车(CR) ,将当前位置移到本行开头 013
\t 水平制表(HT) (跳到下一个TAB位置) 009
\v 垂直制表(VT) 011
\\ 代表一个反斜线字符’’' 092
\' 代表一个单引号(撇号)字符 039
\" 代表一个双引号字符 034
\0 空字符(NULL) 000
\ddd 1到3位八进制数所代表的任意字符 三位八进制
\uhhhh 1到2位十六进制所代表的任意字符 二位十六进制

进制

  • 二进制:以0b开头。(b大小写都行)
  • 八进制:0开头 0~7
  • 十六进制:0x开头 0~9 a~f

其他进制到十进制(位权展开求和)

  • 系数:每一位的数据

  • 基数:x进制,基数就是几

  • 权:从右往左,从0开始编号,对应位置的编号即为该位的权

  • 结果:系数*基数的权次幂之和

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    0b1010 = 1 * 2^3 + 0 *2^2 + 1*2^1 + 0*2^0
    = 8 + 0 + 2 + 0
    = 10

    0123 = 1*8^2 + 2*8^1 + 3*8^0
    = 64 + 16 + 3
    = 83

    0x123 = 1*16^2 + 2*16^1 + 3*16^0
    = 256 + 32 + 3
    = 291

十进制到其他进制

  • 除基取余,直到商为0,余数反转

有符号数据表示:

  • 原码:二进制定点表示法,最高位为符号位,**0为正,1为负**,其余位数表示数值的大小
  • 反码:正数的反码与原码相同,负数的反码:符号位不变,其余按位取反
  • 补码:正数的补码与原码相同;负数:反码加1;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
5的二进制表示:
00000000 00000000 00000000 00000101

-5的二进制表示:5的二进制取反+1
00000000 00000000 00000000 00000101
取反: 11111111 11111111 11111111 11111010
+1 : 00000000 00000000 00000000 00000001
---------------------------------------------
11111111 11111111 11111111 11111011

-5的变5的二进制:-5的二进制-1后取反(结果和-5求补码一样)
11111111 11111111 11111111 11111011
-1 : 00000000 00000000 00000000 00000001
---------------------------------------------
11111111 11111111 11111111 11111010
取反: 00000000 00000000 00000000 00000101

二进制到八进制

  • 从右到左,3为一取,得到对应的8进制数。
1
2
3
001111
001 111 ---> 1 7
0b00111 ---> 017

二进制到16进制

  • 从右到左,4为一取,得到对应的16进制数。
1
2
3
001111
0000 1111 ---> 0 f
0b001111 ---> 0x0f

注释

使用注释的地方?

  1. 修改的代码
  2. 表达不明确的地方
  3. 算法
  4. 分支语句,循环语句
  5. 声明类,接口

注释写法

  1. 单行注释://

  2. 多行注释:/* 内容 */

    • 多行注释不能相互嵌套
  3. 文档注释: /** ……*/ 识别注释后会生成一个帮助文档

    • 使用时间:声明类 类中的成员,接口等
    • 第一段:概要描述,通常用一句话或者一段话简要描述该类的作用,以英文句号结束
      • 详细描述和概要描述要求要空一行
    • 第二段:详细描述,通常用一段或者多段话来详细描述该类的作用,一般每段话都以英文句号作为结束
      • 详细描述中可以使用html标签,如<p>、<pre>、<a>、<ul>、<i>等标签,
      • 通常详细描述都以段落p标签开始。<a>一般用于标注出现的组织的链接
    • 第三段:文档标注,用于标注作者,创建时间,参阅类等信息
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /**
    * show 方法的简述.
    *
    * <p>show 方法的详细说明第一行<br>
    * show 方法的详细说明第二行
    * @param b true 表示显示,false 表示隐藏
    * @return 没有返回值
    */
    public void show(boolean b) {
    frame.show(b);
    }

生成帮助文档

  • 不识别作者,版本:javadoc -encoding UTF-8 -charset UTF-8 -d 输出的文件夹 类.class
    • javadoc -d doc Hello.java
  • 识别作者,版本号:
    • javadoc -d 存储的文件夹 -author -version 类.class
    • javadoc -d doc -author -version Hello.java
  • 了解的选项:
    • -public     访问权限是public
    • -protected   访问权限是public和protected
    • -package    访问权限是public、protected和默认
    • -private 访问权限是public、protected、默认 private

常见的javadoc标记

标签 说明
@author 作者标识
@version 版本号
@return 对函数返回值的描述
@deprecated 标识过期API(为了保证兼容性,仍可用,但不推荐用)
@throws 构造函数或方法会抛出的异常
@exception 同@throws
@see 引用,查看相关的内容,如类,方法,变量等,必须顶头写
{@link 包.类#成员} 引用,同@see,但可写在任意位置
{@value} 对常量注释,如果其值包含在文档中,通过改标签引用常量的值
{@code}} {@code text}将文本标记为code,会被解析成text} ,在Javadoc成只要涉及到类名或者方法名,都需要使用@code进行标记
@param 说明方法的参数
@inheritDoc 用于继承父类中的Javadoc,父类的文档注释,被继承到了子类

javap反编译

  • javap 主要用于帮助开发者深入了解 Java 编译器的机制,反编译Java代码,查看Java字节码

  • 用法:javap <options> <classes>

  • 主要选项有:

    • -version:版本信息
    • -v:输出附加信息
    • -l:输出行号和本地变量表
    • -public:仅显示公共类和成员
    • -protected:显示受保护的/公共类和成员
    • -package:显示程序包/受保护的/公共类和成员 (默认)
    • -p或-private:显示所有类和成员
    • -c:对代码进行反汇编
    • -s:输出内部类型签名
    • -sysinfo:显示正在处理的类的系统信息 (路径, 大小, 日期, MD5 散列)
    • -constants:显示最终常量
    • -classpath <path>:指定查找用户类文件的位置
    • -cp <path>:指定查找用户类文件的位置
    • -bootclasspath <path>:覆盖引导类文件的位置
    • -c:分解方法代码,即显示每个方法具体的字节码
    • -verbose:指定显示更进一步的详细信息
  • 除此之外,目前有很多的反编译工具可以用,来查看Java编译后的代码

    • JD-GUI:一个用 C++ 开发的 Java 反编译工具

示例

  • 代码

    1
    2
    3
    4
    5
    6
    7
    class TestJavap{
    public static void main(String[] args){
    int i=3;
    i++;
    String name = "lily";
    }
    }
  • 反编译

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    javap -c TestJavap
    Compiled from "TestJavap.java"
    class TestJavap {
    TestJavap();
    Code:
    0: aload_0
    1: invokespecial #1 // Method java/lang/Object."<init>":()V
    4: return

    public static void main(java.lang.String[]);
    Code:
    0: iconst_3 //常量0压入操作数栈
    1: istore_1 //把栈顶的值放到局部变量1中,即i中
    //这个个指令,把局部变量1,也就是i,增加1,这个指令不会导致栈的变化,i此时变成4了
    2: iinc 1, 1
    5: ldc #7 // String lily
    7: astore_2
    8: return
    }

  • 代码

    1
    2
    3
    4
    5
    public static int add(int a,int b){
    int c=0;
    c=a+b;
    return c;
    }
  • 反编译Desktop>javap -c TestJavap

    • 局部变量表单额index是从0开始
    1
    2
    3
    4
    5
    6
    7
    8
    0: iconst_0        //常量0压入操作数栈
    1: istore_2 //弹出操作数栈栈顶元素,保存到局部变量表第2个位置
    2: iload_0 //第0个变量压入操作数栈
    3: iload_1 //第1个变量压入操作数栈
    4: iadd //操作数栈中的前两个int相加,并将结果压入操作数栈顶
    5: istore_2 //弹出操作数栈栈顶元素,保存到局部变量表第2个位置
    6: iload_2 //加载局部变量表的第2个变量到操作数栈顶
    7: ireturn //返回

JDK安装

Linux下安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 下载
mkdir -p /usr/local/java/
wget https://d6.injdk.cn/openjdk/openjdk/17/openjdk-17.0.1_linux-x64_bin.tar.gz
tar -xzvf openjdk-17.0.1_linux-x64_bin.tar.gz -C /usr/local/java/

# 配置环境变量
cat >> /etc/profile << 'EOF'
#java环境变量
export JAVA_HOME=/usr/local/java/jdk-17.0.1
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
EOF

source /etc/profile

#验证
java -version
openjdk version "17.0.5" 2022-10-18
OpenJDK Runtime Environment GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08)
OpenJDK 64-Bit Server VM GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08, mixed mode, sharing)