生命不息,学习不止,对一切都要维持敬畏之心。
若有不正之处,请谅解和批评指正,不胜感激。

1.什么是JDK,为什么要装JDK

JDK是Java语言的软件开发工具包.它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。
运行java程序 需要java的运行环境,而我们是开发人员需要使用Java工具进行开发.

1.1为什么要配置JAVA_HOME环境变量

栗子:

  • tomcat

  • maven

  • 总结*
    环境变量是计算机系统的全局变量,供给应用软件使用,而变量名称JAVA_HOME可以理解成各个软件配置的一项约定,大家都使用名字为JAVA_HOME的环境变量,那么它就变成了一种约定.

    1.2关于Eclipse配置

    配置:jdk1.8_201
    现象:无法启动Eclipse,提示信息为缺少jdk11.
    解决:下载jdk11压缩版,解压至例如E:\develope\Java\jdk-11.0.9,找到Eclipse安装目录->eclipse.ini打开,添加-vm E:\develope\Java\jdk-11.0.9\bin保存.
    Eclipse

2.JAVA开发过程

  • 编写源代码
  • 使用javac进行编译,获得.class文件
  • 使用java命令解释运行

2.1JAVA是编译型还是解释型与平台无关性

.java文件->编译->.class文件,编译成.class字节码,.class需要jvm解释,然后解释执行。Java很特殊,Java程序需要编译但是没有直接编译成机器语言,即二进制语言,而是编译成字节码(.class)再用解释方式执行。java程序编译以后的class属于中间代码,并不是可执行程序exe,不是二进制文件,所以在执行的时候需要一个中介来解释中间代码,这既是java解释器,也就是所谓的java虚拟机(JVM).正因为如此,所以java具有平台无关性.

图片说明

2.2 JAVA的安全性

2.21 语言层次的安全性主要体现在:

  • Java取消了强大但又危险的指针,而代之以引用。由于指针可进行移动运算,指针可随便指向一个内存区域,而不管这个区域是否可用,这样做是危险的,因为原来这个内存地址可能存储着重要数据或者是其他程序运行所占用的,并且使用指针也容易数组越界。
  • 垃圾回收机制:不需要程序员直接控制内存回收,由垃圾回收器在后台自动回收不再使用的内存。避免程序忘记及时回收,导致内存泄露。避免程序错误回收程序核心类库的内存,导致系统崩溃。
  • 异常处理机制:Java异常机制主要依赖于try、catch、finally、throw、throws五个关键字。
    强制类型转换:只有在满足强制转换规则的情况下才能强转成功。

    2.22 底层的安全性可以从以下方面来说明

  • Java在字节码的传输过程中使用了公开密钥加密机制(PKC)。

    2.23 在运行环境提供了四级安全性保障机制:

  • 字节码校验器 -类装载器 -运行时内存布局 -文件访问限制

3.数据类型

3.1 基本数据类型

  • Java 是一种强类型语言。这就意味着必须为每一个变量声明一种类型
  • 在 Java 中,一共有 8种基本类型,其中有 4 种整型、2 种浮点类型、 1 种用于表示 Unicode 编码的字符单元的字符类型 char和1种用于表示真值的 boolean 类型。

    3.11整型

    整型用于表示没有小数部分的数值, 它允许是负数。long型后面要加L。Java 没有任何无符号(unsigned) 形式的 int、 long、short 或 byte 类型
    整型

    3.12浮点类型

    浮点类型用于表示有小数部分的数值,float 类型的数值有一个后缀 F 或 f
    浮点型

    3.13char型

    char 类型原本用于表示单个字符。不过,现在情况已经有所变化。 如今,有些 Unicode字符可以用一个 char值描述,另外一些 Unicode 字符则需要两个 char 值。Unicode 转义序列会在解析代码之前得到处理。
    char型

    3.14 boolean 类型

    boolean (布尔)类型有两个值:false 和 true, 用来判定逻辑条件 整型值和布尔值之间不能进行相互转换

4.计算机只能存储0和1,那么一个字符a是如何存储的?

'a'---->ASCII码表----->找到对应的数97----将97转换为二进制存储,二进制的97---->转换为10进制的97------>ASCII码表----->'a'

5.什么是变量?变量如何定义?同一个作用域中变量名是否可以相同?变量可以不赋值直接使用吗?

1.变量->内存中临时存储数据的区域 每个变量都有其数据类型
2.变量的定义格式->数据类型 变量名=变量值;
3.相同作用域下变量名不可以相同
4.变量必须先赋值再使用
5.变量名必须是一个以字母开头并由字母或数字构成的序列
6.尽管 $ 是一个合法的 Java 字符, 但不要在你自己的代码中使用这个字符.
7.不能使用 Java 保留字作为变量名
8.变量名对大小写敏感

5.1.中间缓存变量机制

int i=0;
i=i++;
System.out.println(i);

i=i++;等同于:
temp=i; (等号右边的i)
i=i+1; (等号右边的i)
i=temp; (等号左边的i)
而i=++i;则等同于:
i=i+1;
temp=i;
i=temp;

所以输出为0;

6.常量

在 Java 中, 利用关键字 final 指示常量,关键字 final 表示这个变量只能被赋值一次。一旦被赋值之后,就不能够再更改了。习惯上,常量名使用全大写

7.数组

  • 数组是一种数据结构, 用来存储同一类型值的集合。
  • 在声明数组变量时, 需要指出数组类型
  • 数组下表从0开始
  • 初始化:
    数据类型[] 标识符=new 数据类型[长度]
    数据类型[] 标识符=new 数据类型[]{1,2,3,4,5,6}
    数据类型[] 标识符={1,2,3,4,5,6}
  • 数组拷贝
    浅拷:两个变量将引用同一个数组
    深拷:Arrays.copyOf(原数组,长度)->如果数组元素是数值型,那么多余的元素将被赋值为 0 ; 如果数组元素是布尔型,则将赋值为 false。相反,如果长度小于原始数组的长度,则只拷贝最前面的数据元素
  • 遍历foreach
  • 不同类型数组默认值
    int-> 0
    double-> 0.0
    char-> 空格
    boolean-> false
    引用类型-> null

8.字符串

8.1字符串是不可变量

2021-05-12补充
为什么要设计String为不可变量传送门

字符串
final修饰,目的就是为了多线程可以安全共享.不会造成混乱.

8.2 字符串常量池

  1. JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化为字符串开辟一个字符串常量池,类似于缓存区
    JVM
  • 程序计数器是jvm执行程序的流水线,存放一些跳转指令,这个太高深,小菜不懂。
  • 本地方法栈是jvm调用操作系统方法所使用的栈。
  • 虚拟机栈是jvm执行java代码所使用的栈。
  • 方法区存放了一些常量、静态变量、类信息等,可以理解成class文件在内存中的存放位置。
  • 虚拟机堆是jvm执行java代码所使用的堆。

2021-05-12修正

  • 这个字符串常量区就处于方法区中.
  • 在 JDK 1.8 中, HotSpot 已经没有 “PermGen space”这个区间了,取而代之的是 Metaspace(元空间)。
    元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过以下参数来指定元空间的大小
    引用自废弃永久代迎来元空间
  1. 创建字符串常量时,首先坚持字符串常量池是否存在该字符串.
  2. 存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中.
  3. 甲骨文jdk(1.7),javac会进行常量折叠,全字面量字符串相加是可以折叠为一个字面常量,而且是进入常量池
    常量池
  • 总体来说,new String("A")如果常量池没有"A"则共创建2个对象,如果有"A"则创建一个,变量+常量字符串拼接肯定会新建一个常量池对象,常量+常量拼接只创建一个对象(通过反编译,发现是通过StringBuilder进行的字符串append)

    8.3 关于intern()方法

    用来操作字符串常量池,例如str.intern(),如果存在于常量池,则返回对象的引用,如果不存在,则先在常量池创建一个对象,再返回对象的引用.
    2021-05-12补充一下
  • 来自美团技术团队一篇大佬说明*传送门

9.数据类型转换与拆箱装箱(2021-5-4补充)

  • 大小排序为:byte<shot=char<int<long<float<double

    9.1 隐式转换

  • 从小到大无精度丢失,可直接转换

9.2 强制转换

  • 格式:范围小的数据类型 变量 = (范围小的数据类型)范围大的数据
  • 特点:强制类型转换,数据值的数学意义上的大小会被改变。

9.21 关于byte

图片说明

  • 原因就是在计算过程中,JAVA默认为int类型,而左边依然为byte类型,所以报错,修改如下
    图片说明

9.3 装箱拆箱

  • Java为每种基本数据类型都提供了对应的包装器类型,从Java SE5开始就提供了自动装箱的特性
  • 装箱就是 自动将基本数据类型转换为包装器类型;拆箱就是 自动将包装器类型转换为基本数据类型。
  • 推荐一大哥的帖子传送门

10 运算

10.1计算机基础

10.11 进制换算

  • 在计算机中,所有的数据都是以二进制的形式进行表示的,也就是说,在计算机中使用0和1来表示所有的数据。而我们日常生活中的数字都是10进制的,那我们平时使用的数字如果在计算机中表示时就需要进行进制的转换。
  • R转10如10010011.10->1R^7+0R^6+0R^5+1R^4+0R^3+0R^2+1R^1+1R^0+1R^-1+010^%-2(^表示幂次方)(简便算法8421算法)
  • 10转R->整数部分除R取余逆向排列,小数部分乘以R取整正向排序.
  • 2转8->二进制转八进制时,每三位二进制数表示一个八进制数。因为在八进制中,总共有8个基数,分别是0~7,逢8进1。而如果要使用二进制来表示时,0的二进制为000,7的二进制为111,所以,每三位二进制数对应一位八进制数。反过来,每一位八进制数对应三位二进制数。
    图片说明
  • 2转16->在十六进制表示的数字中,总共有15个基数,为015,逢16进1。如果要将二进制数转化为十六进制数时,首先要弄清楚每位十六进制数需要多少为二进制数表示。在十六进制中,最大的基数为15,15的二进制表示为:1111,最小的基数为0,0的二进制数为0000,也就是说,十六进制的基础使用二进制表示为 00001111,所以,每位十六进制数需要四位二进制数表示。
    图片说明

    10.12 码制

  • 原码,反码,补码
  • 计算机是按照补码存储
  • 正数的原码、反码和补码是相同的。
  • 负数的反码是原码除符号位外,其他位分别取反;
  • 负数的补码是其反码的末位加1。
  • 移码是在补码的基础上符号位取反得到。
  • -以上整理自一大哥,感谢大哥传送门

10.2 位运算(5月8日追加)

11.equal和==(5月12日追加)

11.1.基本数据类型

只能用==,比较的是值,不能用equal

11.2.包装类型

==比较地址,equal比较值

11.3 String类型

==比较地址,equal比较值

11.4 比较对象

==和equal都是比较内存地址,没有被重写的equal方法都是使用的顶层基类Object的equal方法.

12.switch

图片说明

13.关于BigDecimal

标记传送门你以为用了BigDecimal后,计算结果就一定精确了?