Java学习笔记一

Java学习笔记 一

这里写目录标题

  • Java学习笔记 一
    • Java入门基础
      • 1、什么是Java?
      • 2、Java历史
      • 3、JDK
        • JDK和JRE结构详细图
        • 下载网址
        • JDK压缩包安装
          • (1)LInux环境配置
          • (2)Window环境配置
        • JDK目录
      • 4、Java特点
          • 跨平台原理
      • 5、Java中常用命令
      • 6、package
          • 作用:
          • 定义格式:
          • 注意事项:
          • import 导包
      • 7、Java虚拟机
          • 内存模型 (5大块)
      • 8、Java代码编译及运行过程
    • Java中标识符
      • 1、关键字
      • 2、标识符
        • 命名规则:
        • 命名约定:
      • 3、常量
        • 种类
        • 字面值常量:
        • 注意事项:
        • 补充:
      • 4、变量
          • 注意事项:
          • 命名格式:
          • 内存理解:
          • 变量小结:
      • 5、数据类型
        • 两大分类
      • 6、类型转换
        • 种类
        • 隐式类型转换
        • 显式类型转换(强制)
    • 编程语言入门基础
      • 1、注释
      • 2、字节
      • 3、进制
          • 任意进制转换为10进制
      • 4、原反补码
      • 5、操作符
        • (1)、运算符分类
        • (2)、算术运算符
          • 自增自减:
        • (3)赋值运算
        • (4)比较运算符
        • (5)逻辑运算符
          • 补充:(位运算)
        • (6)移位运算符
        • (7)三目运算符
      • 6、流程控制
        • (1)顺序结构
        • (2)分支结构
          • 2.1 if 判断
          • 2.2 if - else
          • 2.3 if-else if -else
          • 2.4 switch
        • (3)循环结构
          • 3.1 for循环
          • 3.2 while循环
          • 3.2 do while循环
          • 3.3 三种循环的区别
          • 3.4 三种循环使用场景
          • 3.5 循环嵌套
        • (4)break
        • (5)continue
        • (6)label
      • 7、作用域
      • 8、方法和函数
        • 8.1 定义格式
        • 8.2 方法调用
        • 8.3方法重载
        • 8.4方法重写
        • 8.2 方法调用
        • 8.3方法重载
        • 8.4方法重写

Java入门基础

1、什么是Java?

Java之父:詹姆斯·高斯林

1991年诞生,最初叫Oak (橡树),1995年改名为Java,英文翻译为印尼爪哇岛,地名,因盛产咖啡而闻名。

2、Java历史

  1. 1991年4月,由James Gosling 博士领导的绿色计划Green 启动项目目的是开发一种能够在各种消费性电子产品(如机顶盒、冰箱等)上运行的程序架构该项目最终的产品是Oak(橡树) ,即Java语言的前身

  2. 1995年5月23日,Oak语言改名为Java,并且在SunWorld大会上正式发布Java 1.0版本
    Java语言第一次提出了Write Once,Run Anywhere的口号

  3. 1996年1月23日,JDK 1.0发布,Java语言有了第一个正式版本的运行环境JDK 1.0提供了一个纯解释执行的Java虚拟机实现(Sun Classic VM)JDK 1.0版本的代表技术包括:Java虚拟机、Applet、AWT等。

  4. 1997年2月19日,Sun公司发布了JDK 1.1,Java技术的一些最基础的支撑(如JDBC等)都是在JDK 1.1版本中发布的Java语法也有了一定的发展,如内部类和反射

  5. 1999年4月8日,JDK 1.1在此期间一共发布了1.1.0~1.1.8九个版本从1.1.4之后,每个JDK版本都有一个自己的名字(工程代号)例如:JDK1.1.4 - Sparkler(宝石)、JDK 1.1.5 - Pumpkin(南瓜)

  6. 1998年12月4日,JDK迎来了里程碑式的版本JDK1.2,代号Playground(竞技
    场)
    Sun公司在这个版本中把Java技术体系拆分为3个方向:
    面向桌面应用开发的J2SE(Java 2 Platform,Standard Edition)–>JavaSE,Java基础,是其他两个方向的基石
    面向企业级开发的J2EE(Java 2 Platform,Enterprise Edition)–>JavaEE现目前的主流方向
    面向手机等移动终端开发的J2ME(Java 2 Platform,Micro Edition)

  7. 1999年4月27日, HotSpot虚拟机发布HotSpot最初由一家名为"Longview Technologies"的小公司开发,因为HotSpot的优异表现,这家公司在1997年被Sun公司收购了HotSpot虚拟机发布时是作为JDK 1.2的附加程序提供的,后来它成为了JDK1.3及之后所有版本的Sun JDK的默认虚拟机

  8. 2004年9月30日, JDK1.5 发布,代号Tiger(老虎)从JDK 1.2以来,Java在语法层面上的变换一直很小,而JDK1.5在Java语法易用性上做出了非常大的改进
    例如,自动装箱、泛型、动态注解、枚举、可变长参数、遍历循环(foreach循环)等语法特性都是在JDK 1.5中加入的

  9. 2006年12月11日,JDK 1.6发布,代号Mustang(野马)在这个版本中,Sun终结了从JDK 1.2开始已经有8年历史的J2EE、J2SE、J2ME的命名方式启用Java SE 6、Java EE 6、Java ME 6 的命名方式。

  10. 2006年11月13日,在JavaOne大会上,Sun公司宣布最终会将Java开源

  11. 2009年2月19日,工程代号为Dolphin(海豚)的JDK 1.7完成了其第一个里
    程碑版本

  12. 2009年4月20日,Oracle公司宣布正式以74亿美元的价格收购Sun公司,Java
    商标从此正式归Oracle所有

3、JDK

相关名词:

SDK (software development kit),软件开发包,主要包含函数库或者工具等
JDK (java development kit),Java程序开发工具包,面向Java程序的开发者
JRE (java runtime enviroment),Java程序运行环境,面向Java程序的使用者
API (application program interface),应用程序编程接口
API Documentation,API说明文档,描述API中的类、方法等使用的方式

JDK和JRE结构详细图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7r58NrRe-1692457087760)(./image/JDK和JRE结构详细图.png)]

JDK和JRE关系简略图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vvI06qwl-1692457087762)(./image/JDK和JRE关系简略图.png)]

JDK是开发环境,包括开发中的一些开发工具(jar包)和 jre 运行的环境

JRE只是运行环境,不包括其他的开发包,只需要运行Java的字节码文件

下载网址

JDK8:https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html

JDK历史版本:https://www.oracle.com/java/technologies/downloads/

JDK8在线文档:https://docs.oracle.com/javase/8/index.html

个版本API说明文档下载:https://www.oracle.com/java/technologies/downloads/

JDK8-API文档下载地址:https://www.oracle.com/java/technologies/javase-jdk8-doc-downloads.html

JDK压缩包安装
(1)LInux环境配置

压缩包解压并解归档

打开~/.bashrc

添加一下三个路径配置:

​ JAVA_HOME=路径

​ PATH=%JAVA_HOME%\bin;

​ CLASSPATH=.

配置完成后:java -version查看Java版本,验证是否配置成功

Java学习笔记一_第1张图片

(2)Window环境配置

win10 打开环境变量(

方式一:控制面板 —> 系统安全 —> 系统 —> 高级系统设置 —> 环境变量;

方式二:win + i —> 系统 —> 关于 —> 高级系统设置 —> 环境变量;

方式三: win + R —> sysdm.cpl—> 高级 —> 环境变量 )

配置系统变量:

​ 添加 JAVA_HOME:路径

​ CLASSPATH=. (注:这是一个英文点)

​ Path = %JAVA_HOME%\bin;

配置完成后:win + R —> cmd —> java -version查看Java版本,验证是否配置成功

Java学习笔记一_第2张图片
Java学习笔记一_第3张图片

注:Path中添加JAVA_HOME依次添加在2其他环境变量后,不过注意是否有其他的JDK的环境变量,扫描是从上到下,找到就不会接着找,上面有,后面的环境变量会失效。其次为了像图中的列表显示Path配置,最好将C:\Windows\System32 这个配置放在最上面。

JDK目录
目录/文件 作用
bin目录 存放JDK中提供的Java各种工具命令(可执行程序,二进制文件),如java、javac、javap等
db目录 JDK自带的一个小型数据库,纯Java实现
include目录 JVM启动时需要引入的一些特定头文件(C语言实现)
jre目录 JDK中自带的一个Java运行环境
lib目录 "library"的缩写,目录中提供了一些Java类库和库文件,即jar包
src.zip文件 压缩文件,目录存放JDK核心类的源代码,也就是JavaSE-API的源代码

Java学习笔记一_第4张图片

src.zip 和 rt.jar 的关系:

Java 是开源的,在下载JDK时会附带其源码(.java文件),所以 src.zip 中就是 Java源码的压缩。

rt.jar 存放的是使用的类(.class文件),JVM会先从这个 rt.jar 中去调用类。

关系: sun公司程序员 --> 编写基础的代码 --> *.java --> 压缩 --> src.zip --> 编
译 --> *.class --> 归档 --> rt.jar

4、Java特点

Java 语言是一种分布式的面向对象语言,具有面向对象、平台无关性、简单性、解释执行、多线程、安全性等很多特点,具体如下:

  1. 纯面向对象编程,简单、开发速度快
  2. 一次编写,到处运行(Write Once,Run any Where)
  3. 跨平台
  4. 开源及强大的生态环境,社区活跃,第三方类库选择丰富
  5. 强大的 API ,使得编程变得更加容易快捷,大大降低了程序的开发成本
  6. 安全性,Java 的存储分配模型可以有效防御恶意代码攻击
  7. 支持多线程和多任务
  8. 强类型、异常处理、垃圾回收机制等技术,保证了 Java 的健壮性
跨平台原理

Java语言是混合型(编译+解释)高级语言

首先Java的源代码需要编译,才能运行,编译后生成与平台无关的字节码(.class文件; 其次,字节码文件不能直接执行,需要交给其操作系统下的Java虚拟机(JVM)解释执行,而Java为不同的操作系统提供了不同的JVM虚拟机,这样在不同操作系统中,能够用不同的JVM 解释同一份编译后的字节码文件,运行出相同效果。

其中,JVM就类似于翻译器,将同一句话,翻译成不同国家的语言,表达的意思是一致的。Java不用再修改代码去适应不同操作系统,而是底层不同的操作系统对应的JVM帮我们完成了此过程。

Java学习笔记一_第5张图片

5、Java中常用命令

java -version # 查看Java版本信息
javac [-d 编译后存放的目录路径] *.java # 编译Java文件
java [-cp class文件存储目录] 类的全包名 # 运行.class文件
javadoc #生成API文档
javap .class文件 # 反编译命令
jar # 打包命令

6、package

Java中, package 其实就是类的命名空间,用来唯一标识类的,同时也把类似功能的类组织到一个包中,package就相当于文件夹。

作用:

解决命名冲突问题,不同包可以使用相同名字

组织类,使相同功能放在一起,便于管理

定义格式:

package 包名;
多级包用" . " 作为分隔符

注意事项:

package语句必须是程序的第一条可执行的代码
package语句在一个Java文件中最多只能有一个
程序中可以不用package,表示无包名
包其实就是文件夹,一般是公司域名倒着写

import 导包

格式:

import 包名.类名;

注意:导包位置是在package之下,第一个类名之上

Java中不同包的类使用时都需要导包,除JDK的java.lang包除外,该包下有经常使用的类,Java自动默认帮我导入,减少了每次使用java.lang中的类就要导包的不必要的麻烦,提高了效率。

7、Java虚拟机

JVM是Java Virtual Machine(Java虚拟机)的缩写,它是一个虚构出来的计算机规范结构,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

内存模型 (5大块)

类加载

运行时数据区(5块)

虚拟机栈 (方法调用就入栈,方法结束就出栈)

​ 虚拟机栈中的局部栈帧又有

局部变量表

操作数栈

动态链接

返回地址

本地方法栈

堆 (主要存放对象和引用数据类型,凡是new出来的几乎都在堆中开辟内存空间)

方法区 (用于存储JVM加载(class文件)完成的类型信息、常量、静态变量,有静态常量区,不过在JDK1.8 后被移入堆中)

程序计数器 (用来记录命令的执行顺序)

注: 我们主要关注虚拟机栈(常称为栈)、堆、方法区这三大块。

还有,栈是线程隔离的,堆和方法区是线程共享的)

执行引擎

本地接口库

本地方法库

:有些将本地接口库和本地方法库归结为一大块,不过影响并不大,此模块中底层并不对我们开放,使用C++/C实现的,我们不需要关注太多,一些方法,能过调用即可,JVM底层自己会自动调用)

Java学习笔记一_第6张图片
Java学习笔记一_第7张图片

附:知乎一篇JVM底层原理的讲解:https://zhuanlan.zhihu.com/p/25713880

8、Java代码编译及运行过程

Java学习笔记一_第8张图片

由图可以知道Java分为两个过程:编译时、运行时。(也就在错误和异常就有编译时、运行时两种,编写代码一些问题就需要从这两方面去考虑,多态也是分为编译时和运行时等等,这些都是由Java实现架构导致的)

编译时:.java 文件转换成 .class文件(字节码文件)

Network:表示的是从运行时到编译时的途径:可以是本地、也可以是网络远程……(这充分体现了Java的夸平台特性)

运行时:字节码文件首先会进行类加载,然后会进行字节码验证,之后大部分class文件会通过解释器解释运行后加载要内存,少部分class文件通过即时编译器后加载到内存中。

字节码验证的内容:

  1. 检查当前class文件的版本和JVM的版本是否兼容
  2. 检查当前代码是否会破坏系统的完整性
  3. 检查当前代码是否有栈溢出的情况
  4. 检查当前代码中的参数类型是否正确
  5. 检查当前代码中的类型转换操作是否正确

Interpreter(解释执行)

class文件内容,需要交给JVM进行解释执行,简单理解就是JVM解释一行就
执行一行代码。所以如果Java代码全是这样的运行方式的话,效率会稍低一

JIT(Just In Time)即时编译

执行代码的另一种方式,JVM可以把Java中的热点代码直接编译成计算机可
以运行的二进制指令,这样后续再调用这个热点代码的时候,就可以直接运
行编译好的指令,大大提高运行效率。

垃圾回收器

垃圾回收器(Garbage Collection,GC),目前在此处做了解。

GC是守护线程,主要回收未使用的对象。

Java中标识符

1、关键字

JDK中已经预定的单词,具有特殊的含义,在命令时不能单独使用关键字。组成关键字的字母全部小写,常用的代码编辑器对关键字都有高亮显示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wImYFKLA-1692457087767)(./image/关键字.png)]

(注: const和goto是保留字,Java目前并作为关键字,可能以后会加入,所以我们在命令时也不能使用,避免以后Java加入后导致一些已经编译的程序报错。另外,true 和 false 不是关键字,是boolean类型的字面值,但是也不能用做自定义标识符)

2、标识符

在Java中给类、方法、变量起的名字,就是标识符,其可以用来标识这个类、方法、变量

命名规则:
  1. 标示符可以由字母、数字、下划线_ 、美元符号$组成
  2. 标示符开头不能是数字
  3. 标识符中的字符大小写敏感
  4. 标识符的长度没有限制
  5. 标示符不能使用Java中的关键字或保留字
命名约定:

双驼峰命名法(首字母大写,单词首字母也大写):类(普通类、抽象类、枚举类等)和接口

小(单)驼峰命名法(首字母小写,单词首字母大写):方法、变量、属性

字母全部大写:常量(final static 修饰的变量)

(注:起名需要简明知意,一些命名可以用通俗的缩写)

3、常量

其值不可以发生改变的量,称为常量

种类

字面值常量: 常量值
自定义常量:final static 修饰的变量

字面值常量:

字符串常量
用双引号括起来的多个字符(可以包含0个、一个或多个)

例如:“”、“a”、“abc”、"中国"等

字符常量
用单引号括起来的一个字符

例如:‘a’、‘5’、‘B’、'中’等

(注: 无论是否是字符还是字符串都是字符字面常量,其存储在静态常量池中,String类型的字符串底层也是用char来实现的)

整数常量
整数值,(int是默认字面整型常量)

例如:-10、0、88等

浮点常量
小数值,(浮点默认字面常量是double类型)

例如:-5.5、1.0、88.88等

布尔常量

布尔值,表示真假,只有两个值: true、false

空常量

一个特殊的值,空值: null

注意事项:

除空常量外,其他常量均可使用输出语句直接输出
字面值常量这个词,这个字面值是固定、不可改变的,即常量值 (在之后的数据类型转换时会使用字面值的运用,不注意字面值容易在转换时报赋值类型错误,或类型转换失败)

补充:
  1. 整形字面值,不论是二进制、八进制还是十进制、十六进制,默认都是int类型常量。
  2. 整形数后面加’L’或’l’,就表示long类型字面值常量
  3. 小数后面加’F’或’f’,就表示float类型字面值常量

4、变量

变量是用来标识开辟的一块内存空间,字面意思就是可变的量,因为可以称作是容器,容器可以换着装不同的东西,不过Java中的变量装东西有一定的限制。

注意事项:

变量一定要求 先声明、再赋值 、之后才能使用

命名格式:

格式一:

数据类型 变量名; (声明过程)
变量名 = 数据值; (赋值过程)

格式二:

数据类型 变量名 = 数据值; (声明的同时赋值)

内存理解:

单个变量内存理解:

Java学习笔记一_第9张图片

多个变量内存理解:

Java学习笔记一_第10张图片

变量小结:

变量名是标识符中的一种,用来标识一块内存区域
变量定义后没有赋初值,不能直接使用,否则编译报错
变量值的类型应该跟变量的类型一致(注意字面值和数据类型)

5、数据类型

两大分类

基本数据类型 (8种)
引用数据类型

Java学习笔记一_第11张图片

额外说明:
e+38表示是乘以10的38次方,同样,e-45表示乘以10的负45次方。

注意一个坑:String 不是基本数据类型,尽管它十分常用,但是但是java.lang.String下的类,是引用类型。

6、类型转换

种类

隐式类型转换
显式类型转换

基本数据类型表示范围大小排序:

在这里插入图片描述

隐式类型转换

赋值过程中,小数据类型值或变量可以直接赋值给大类型变量,类型会自动进行转换

  1. byte、short、char类型的数据在进行算术运算时,会先自动提升为int,然
    后再进行运算
  2. 其他类型相互运算时,表示范围小的会自动提升为范围大的,然后再运算
显式类型转换(强制)

赋值过程中,大类型数据赋值给小类型变量,编译报错,此时必须通过强制类型转换实现。

转换格式:

数据类型 变量名 = (目标数据类型)(数值或变量或表达式);

注意事项:

强制类型转换时,得到的结果值可能会与期望值不同,可能会造成精度缺失

其他情况

整形常量优化机制 :

​ 使用整形字面值常量赋值时,系统会先判断该字面值是否超出赋值类型的取值
范围,如果没有超过范围则赋值成功,如果超出则赋值失败。

注意事项:

  1. 常量优化机制只适用于常量,如果是变量,则不可以
  2. 常量优化机制只针对int类型常量,对于long、float、double等常量,则不可以

编程语言入门基础

1、注释

Java中三种:(其他语言也差不多一样,注释采用的都是约定俗称的规范)

单行注释

符号:“//”

顾名思义,就是注释的范围是位于*//* 注释符开始后的一整行

多行注释

符号:/* */

以"/**" 开始,到 “*/” 结束,符号范围内的多行内容,主要指符号范围,所以也可以用以可以注释一行

注: 多行注释是不能嵌套的,原理很简单,头尾符号在中间嵌套后就被分割为三部分,而中间部分是不被注释的)

文档注释

符号:/** 文档注释内容 */

主要用于类上和一些方法上,用于生成doc文档

2、字节

字节:byte,是计算机 分配内存 的最小单位,通常用大写字母“B”表示。了解字节首先要了解比特位(bit) ,存放一位二进制数,即 0 或 1(只有两种可能性,计算机最原始或底层的表现形式),是计算机 存储信息 的最小单位,一个字节包含了8个比特位,即: 1byte == 8bits。比特位可以用作二进制计算,不过在计算机存储单位计算一般都是以字节为最小单位。

计算器存储容量的单位,常见的还有KB、M、G、T,换算过程如下:

1KB (Kilobyte 千字节) = 1024B,—> 1024=2^10位 ( 2 的10次方)
1MB (Megabyte 兆字节 简称“兆”) = 1024KB ,—> 1024=2^20位 ( 2 的20次方)
1GB (Gigabyte 吉字节 又称“千兆”) = 1024MB—> 1024=2^30位 ( 2 的30次方)
1TB (Trillionbyte 万亿字节 太字节) = 1024GB—> 1024=2^40位 ( 2 的40次方)

3、进制

计算机底层使用的是二进制,0和1只有真假两种可能性,就类似于阴阳。进制就是逢几进位,二进制就是遇二进进一位一位,也就是只有0、1,七进制就是逢七进一,只有06的数字,八进制就是逢八进一,只有07的数字,十进制就是逢十进一,只有09的数字,十六进制进制就是逢十六进一,只有0F的表示,其他同理。不同进制之间存在转化关系。

二进制 0b|B开头,由0和1组成
八进制 0开头,0、1…6、7组成
十进制 常用的整数,0、1…8、9组成
十六进制 0x或0X开头

任意进制转换为10进制

转换方式:

结果值 = 系数*基数的权次幂相加
系数:每一位上的数据
基数:X进制,基数就是X
权:最右边那位对应0,每左移一位加1

十进制转换为其他进制 : 除积倒取余

Java学习笔记一_第12张图片

十进制到二进制的快速转换
二进制的从右往左一位都表示2的(n -1) 次方,直接将2次方的和相加即可。

Java学习笔记一_第13张图片

二进制转换为8、16进制技巧:

原理:8、16都可以转化成2的幂次方,同理2的幂次方都可以参照

8进制,从右往左,依次按三位分一组,高位不够补0,每三位计算出一位8进制数,最后依次拼接即可。

16进制就每四位分一组,其他与8进制同理。

4、原反补码

原反补码都是数在计算机底层的二进制形式

(注意:有符号的数据类型 的二进制位数包括最高位符号位,该位数一般情况只是符号标志,不作为计数位;0为正数、1为负数)

原码:

正数:与原二进制形式相同 10的原码:0 0… 0000 1010

负数:最高位为1,计数位与数的绝对值的二进制数形式一致 -10的原码:1 0…0000 1010

反码

正数:与原码一致 10的反码: 跟10的原码相同 0 0… 0000 1010

负数:在原码的基础上,保留符号位,其他位逐位取反 -10的反码: 1 1… 1111 0101

补码

正数:补码与其原码相同 10的补码: 0 0… 0000 1010

负数:其反码的末位加1 -10的补码: 1 1 1…1111 0110

注: 原返补码都是为了解决数在计算机中的表示形式,原码是最接近数的表示形式,但是它在计算中存在问题,负数的计算结果与实际不符,所以才出现了反码;虽然反码解决了一部分问题,但是无法界定 0 的问题,在反码中存在正 0 和 负 0 ,有两个 0 ,但是 0 是没有正负的,有且只有一个,所以此时又出现了补码来解决问题;补码充分解决了 0 的问题,又能准确的进行结算,所以计算在进行数的运算时,是先从原码转换成补码,用补码进行计算的,最后在转换成原码输出出来。简而言之,我们学习时需要学会原返补码的正转换,还有补反原码的逆转换,学会了将对我们编程过程中的数据处理有很大帮助,能助我们理解数据溢出等问题。最后,这里只是一些简单的学习,这些都是属于计算机组成原理中的内容,想要进一步深入了解,就去学习计算机组成原理。

补码的计算小技巧:

1111 11…11 1111 1111 全是1时表示-1

1111 11…11 1111 1110 这是-2

1111 11…11 1111 1101 这是-3

依次类推,得其他负数。其次,由此可知为什么负数的表示范围比正数要多 1 ,答案就在符号位,负数最高位为1。正数加到最高位后符号位就变为了1,成为了负数,而负数本身就是 1 。

5、操作符

​ 操作符,即运算符:对字面值常量或变量进行操作的符号

​ 表达式:用操作符把字面值常量或变量连接起来的并符合相应语法规则的式子。

(1)、运算符分类
  • 算术运算符
  • 赋值运算符
  • 比较 | 关系 | 条件 运算符
  • 逻辑运算符
  • 位运算符
  • 三目运算符

Java学习笔记一_第14张图片

(2)、算术运算符
操作符 作用 例子
+ 数字之间使用+,表示俩个值相加 int a = 1+1
- 两个数字相减 int a = 1-1
* 两个数字相乘 int a = 1*1
/ 两个数字相除 int a = 1/1
% 两个数字取余 int a = 5%2

注:" + " 的特殊性,Java中 “ + ” 还表示字符的拼接的含义, “ + ” 的表达式中带有字符时,需要注意此时最后的结果是字符串,在带有字符的表达式中,小括号内的数与数是先进行正常的数值计算,在进行字符的拼接。简而言之,字符串 + 其他任意类型数据,得到的结果都是字符串。

” % “ 运算符,结果的正负只与被求模的数(左操作数)的正负有关,与模数的正负无关。计算机中,mod 运算实际是做的多次减法,最后结果的 余数 + 模数 * 做减法的次数 = 被求模的数(注意这是验证方法,并不是计算原理)。求模运算的计算效率较低,一般一些移位算能够替换的,会选择替换成位移运算,因为移位运算的效率非常高,直接对二进制数进行操作。

n = 13 % 5;  //  3 ——>  2* 5 +  3
n = -13 % 5; // -3 ——> -2* 5 + -3
n = 13 % -5; //  3 ——> -2*-5 +  3
n = -13 % -5; //-3 ——>  2*-5 + -3
自增自减:

++为自增,–为自减,两者使用方式类似。

自增或自减有两种使用方式,分别如下:

变量名++; 变量名–;

++变量名; --变量名;

单独使用,都对变量进行自增或自减,2种方式作用相同,没有区别,可以看做:

a++ / ++a ——> a = a + 1;

a-- / --a ——>a = a - 1;

如果作为表达式使用,也就是还有其他的运算,则两者不一样:

a++ 是先赋值后加,++a是先加后赋值

a++ ——> a = a; a = a + 1;

++a ——> a = a + 1; a = a;

(从字节码的角度理解是对操作数栈的取值不同,需要具备一定的字节码基础,此处便不再展开讲,从更常用的用法总结来说,口决:a++ 是先赋值后加,++a是先加后赋值;形式上计算机正常情况下读取代码是从上到下,从做到右,a++,a在前,靠近“=” 先赋值,“++” 在后,依次下来就是,加法运算,也就是赋值之后再进行加法运算;++a,"++"在前,靠近“=” 先赋值,“a” 在后,先进行加法运算后再进行赋值)

a-- 是先赋值后减,–a是先减后赋值 (自减与自加形式和原理一致)

a-- ——> a = a; a = a - 1;

–a ——> a = a - 1; a = a;

int x = 4;
int y = (x--) + (--x) + (x * 10);
System.out.println("x: " + x); // x: 2
System.out.println("y: " + y); // y: 26
(3)赋值运算
操作数 作用 例子
= 最基础的赋值操作符,=号右边的值,赋给 = 号左边变量 int a = 1;
*= 一个变量和另一个数据相乘,并把结果再赋值给这个变量 a*=2—>a= a*2
/= 一个变量和另一个数据相除,并把结果再赋值给这个变量 a=2—>a= a\2
%= 一个变量和另一个数据相余,并把结果再赋值给这个变量 a%=2—>a= a%2
+= 一个变量和另一个数据相加,并把结果再赋值给这个变量 a+=2—>a= a+2
-= 一个变量和另一个数据相减,并把结果再赋值给这个变量 a+=2—>a= a+2

除此之外,还有<<= 、 >>= 、 >>>= 、 &= 、 ^= 、 |= 等符合的位运算,见其符号便能知其意。

注: :“ = ”直接赋值是没有带有强转的,但是 +=、-=、*=、/= 等扩展的赋值运算符,隐含了 强制类型转换

(4)比较运算符
操作符 作用 例子
> 比较是否大于 1>0
>= 比较是否大于等于 1>=0
< 比较是否小于 1<0
<= 比较是否小于等于 1<=0
== 判断左右2个操作数是否相等,结果为boolean值 a==b
!= 判断左右2个操作数是否不相等,结果为boolean值 a != b
instanceof 判断对象是否属于指定类型(一般用作对象向下强转时做判断用,防止异常) stu instanceof Student

比较,一般用作布尔表达式和循环条件判断用,它们计算结果返回的是boolean值,比较本身就具有判断,简而言之,比较就是用做判断。

(5)逻辑运算符
操作符 作用 例子
&& 与运算,带逻辑短路 a && b,a、b可以是表达式,两者都为true结果为true,否则为false
& 与运算 a & b,a、b都为true结果为true,否则为false
|| 或运算,带逻辑短路 a || b,a、b可以是表达式,两者都为false结果为false,否则为ture
| 或运算 a & b,a、b都为false结果为false,否则为true
非,取反的意思 !a,如果a为true则结果为false,a为false结果为true
^ 异或,相同为假,不同为真 a ^ b,如果a和b中一个为false,另一个为true则结果为true,否则结果为false

注:带有逻辑短路意味着如表达式 a&&b ,只要能够前面的一个表达式能够判断出结果就不会执行后面的表达式,也就是此次a 能够判断出整个布尔表达式的结果,就不会执行b。如果后面的表达式中(b表达式)含有对后面程序影响的结果,那么带有逻辑短路和不带逻辑短路的结果可能会不一致,这可能导致程序出现歧义。

逻辑运算联想二进制,0 / 1 可以代表真假,也就是true 和false 两种可能 (实际上boolean,在底层并不是用true 和 false 来表示,也就是没有true 和 false,而是用0 、1 表示的)

补充:(位运算)
操作符 作用 例子
& 与运算 1&1=1,1&0=0, 0&1=0, 0&0=0
| 或运算 1 | 1=1,1 | 0=1, 0 | 1=1, 0 | 0=0
^ 异或运算 11=0,0&0=0,10=1, 0&1=1,
~ 取反运算 ~1 —> 0,~0 —>1

位运算没有什么可好解释的,就是对二进制数进行操作,更是一种通过二进制的思想去解决问题。因为计算机底层是二进制,位运算相当于直接对数的原始形式进行操作,效率相当的快。需要慢慢的去使用,体会这种解决问题的思想,将对学习编程会有很帮助。除此之外,能熟练使用位运算对数进行运算,非业内人士看不懂,这不就是展现技术的时候?形象一下就提升!

^ 的一个特殊用法,是不使用中间变量使用来交换两个数。这是利用的异或的特性,

a^ a =000……000 ; a^ a^ a = a

//交换a,b
public static void swap2(int a,int b) {
	System.out.println("交换前:a: " + a + ",b: " + b);
    // 一个数 异或 另一个数 2次,结果是自己
    a = a ^ b;
    b = a ^ b; // a^b^b ==> a
    a = a ^ b; // a^b^a ==> b;
    System.out.println("交换后:a: " + a + ",b: " + b);
}

(6)移位运算符
操作符 作用 例子
>> 算术右移位运算,也叫做【带】符号的右移运算 8 >> 1
>>> 算术右移位运算,也叫做【不带】符号的右移运算 8 >> 1
<< 左移位运算 8 << 1

“>>” 从左往右移位, 低位抛弃,高位补【符号位的值(符号位是0则补0;反之,是1则补1)】

" >>> " 低位抛弃,高位补只0 (正数的值可能不会有变化,但是负数右移,则可能会变成一个非常大的负数)

“<< ” 从右往左移位,高位抛弃,低位补0

10 >> 1 // 5
10 >>> 2 // 2 (10位正数,位移后得到的值也是整数)
-10 >>> 2 // 1073741821
10 << 1 // 20
10 << 2 // 40
-10 << 2 // -40

从以上示例可以知道,左移和不带符号右移,数的正负不影响位移后的结果,并且,右移相当于对数 ÷ 移位次数的 2 次方,左移相当于对数 x 移位数的 2次方。

带符号的算符右移">>>",负数移位后的数可能会是一个很大的正数。无论是否是带符号的算术位移符,这都是通过对数补码进行操作计算而来的。

(7)三目运算符

格式:(关系表达式) ? 表达式1 : 表达式2;

解释:如果关系表达式成立(结果为true),则返回表达式1,(结果为false)否则返回表达式2。

// (关系表达式) ? 表达式1 : 表达式2;
// 可以转换为:
if (关系表达式){
    表达式1
} else {
    表达式2
}
// 其实反编译后的结果就是这样的,这就是Java中的语法糖

注: 三目运算符,是一些高级语言中对if - else 的简写,使代码更加简洁。但是在Go中是没有三目运算的,因为Go奉行,一件事最好只能有一种做法。

6、流程控制

​ 在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的。所以,我们必须清楚每条语句的执行流程。而且,很多时候要通过控制语句的执行顺序来实现我们想要的功能。

​ 需要执行的代码,其结构主要分为以下三种:

  • 顺序结构

  • 分支结构

  1. if语句

    普通if

    if - else

    if - else if - else (多if - else)

    三目运算

  2. switch分支语句

  • 循环结构
  1. for循环
  2. while循环
  3. do while循环
  • 跳转语句

goto(Java中不支持,其他语言支持,如C、C++、Python、GO等,一般也是不用,goto是在是在源码级别上的跳转、不是汇编代码级别,使用goto会使程序变得混乱,所以很少用,一般做了解)

java中又 label 标签,这是用在迭代(简单理解就是循环)中,用break、continue跳转

break

continue

(1)顺序结构

​ 顺序结构就是最基本的流程控制,只要将代码从上到下,按照顺序依次编写即可,大多数代码都是这样的结构,如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BQJVWFu9-1692457087776)(./image/顺序结构.png)]

顺序结构更是一种思想,程序的执行需要从入口处,开始执行,直到到出口处结束程序,顺序结构就是计算机选择的程序执行方式,这应该做为一种理所应当的意识,有时候在遇见一些问题时有意识的去结合这种从上到下顺序执行的思想,遇到的问题就能够迎刃而解,柳暗花明又一村。

当然,程序也不是一定得顺序执行,这是计算机的默认方式,通过跳转语句可以不按顺序结构执行,所以我才说这个顺序结构是一种思想,不仅仅是运用在程序中,计算机的特性,也是生活中的映射在计算机中的体现。

(2)分支结构
2.1 if 判断
if (关系表达式) {
   语句体;
}
/* 当语句体只有一句时,可以加{},也可以不加,Java开发的阿里手册是建议加的
* 作为一名Java开发者,建议去看看阿里的java开发手册(免费),看看大厂的开发标 准,规范很重要,这也是学计算机的一个常识,缺少规范,可能会变得混乱。
*/

执行流程:

  1. 计算 关系表达式 的值
  2. 如果关系表达式的值为true,就执行语句体
  3. 如果关系表达式的值为false,则不执行语句体
  4. 继续执行if代码块后面的其他代码

Java学习笔记一_第15张图片

2.2 if - else
if (关系表达式) {
	语句体1;
} else {
	语句体2;
}
/* if 和 if - else 的区别,if 是判断是否执行if的语句体,是单独的语句,语句中没有return等结束或跳转程序的语句,是不影响上下的程序执行,if 是一个单独的独立体,也就是说多个if语句 连续连续出现时,if 语句之间互不影响。
if - else 就是非此即彼的关系,不是执行if语句就是else语句,从上到下依次判断,有一个判断为true执行了代码,那么后续判断都不再执行,if语句结束;如果判断都为false,则执行else语句代码;这就让两个独立的if语句建立起了紧密关系。
if 和 if-else 在逻辑上存在差异,两者也可以互相转换,实际使用中根据需求选取。在阿里Java规范手册中,建议简单的if - else 用多个if 替换。
 */

执行流程:

  1. 计算 关系表达式 的值
  2. 如果关系表达式的值为true,就执行语句体1
  3. 如果关系表达式的值为false,就执行语句体2
  4. 继续执行if代码块后面的其他代码

Java学习笔记一_第16张图片

2.3 if-else if -else
if (关系表达式1) {
	语句体1;
}
else if (关系表达式2) {
	语句体2;
}else {
	//else代码;
}
/* 用法和if-else 一样,这个是用来进行多个条件判断的。
 * else{} 可以加也可以不加,不加就变成 if-else if
*/

执行流程:

  1. 首先计算 关系表达式1 的值
  2. 如果表达式1的值为true,就执行语句体1;如果值为false就计算关系表达式2的值
  3. 如果表达式2的值为true,就执行语句体2;如果值为false就计算关系表达式3的值
  4. 如果上面关系表达式结果都为false,就执行else代码
  5. 如果中间有任何一个关系表达式为true,那么执行完对应的代码语句之后,整个if-elseif-else退出

Java学习笔记一_第17张图片

2.4 switch

​ switch语句也称为分支语句,其和if语句有点类似,都是用来判断值是否相等,但switch默认只支持byte、short、int、char这四种类型的比较,JDK8中也允许String类型的变量做对比。

switch (表达式) { //表达式可以为byte、short、int、char,JDK5加入枚举,JDK7加入String
    case 1: //分支入口
    	语句体1;
    	break;
    case 2: //分支入口
        语句体2;
        break;
    ...
    default:
        语句体n+1;
        break;
}
/* case语句中一般需要添加break,否则就会执行完case语句体会继续执行直到遇见break,或者执行完整个switch后结束,这就是go语言中说的穿透。不过有特定的需求是不去加break,除此之外一般都会加上。
另外,default语句也不是一定要放在最后,可以赶在switch语句的任意位置,不过一般是放在最后,便于阅读
*/

Java学习笔记一_第18张图片
Java学习笔记一_第19张图片

(3)循环结构

​ 循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句。

​ 死循环:循环一直执行,导致程序无法结束。当反复执行这个循环体时,需要在合适的时候把循环判断条件修改为false,从而结束循环,否则循环将一直执行下去,形成死循环。

(当然使用break等方式可以结束正常和死循环)

3.1 for循环
for (初始化语句1; 条件判断语句2; 条件控制语句4) {
	循环体语句3;
}
/* for循环正常的执行顺序是 初始化语句1 —> 条件判断语句2 (判断是否结束循环) —> 循环体语句3 —> 条件控制语句4*/
// for的死循环
for (; ; ) {
	循环体语句3;
}

执行流程:

  1. 执行初始化语句1
  2. 执行条件判断语句2,看其结果是true还是false
    如果是false,循环结束
    如果是true,执行循环体语句3
  3. 执行条件控制语句4
  4. 回到步骤2继续执行

Java学习笔记一_第20张图片

3.2 while循环

​ 一般情况下,循环次数是确定的,选择for循环,如果循环的次数无法确定,选择while循环。

while (条件判断语句1) {
    循环体语句2;
    条件控制语句3;
}
/* 一个小细节,Java中条件判断是布尔表达式(也就是结果是true或false的),直接使用数值0、1 等是会编译报错的。不过在其他语言中的可以的,比如C、C++,中while(1)就约等于Java中while(true),这有可能会是Java面试题中的一个坑 */
// while死循环
while (true) {
    循环体语句2;
}

执行流程:

  1. 执行初始化语句1
  2. 执行条件判断语句2,看其结果是true还是false
    如果是false,循环结束
    如果是true,执行循环体语句3
  3. 执行条件控制语句4
  4. 回到步骤2继续执行

Java学习笔记一_第21张图片

3.2 do while循环

​ do-while也可以实现循环,但应用较少。

do {
    循环体语句1;
    条件控制语句2;
}while(条件判断语句3);
/* do-while 和while的区别在于do-while在判断前先执行一次循环体,while是先判断后循环;另外,两者是能够互相转换的。 */
// do-while死循环
do {
    循环体语句2;
} while (true);

Java学习笔记一_第22张图片

3.3 三种循环的区别

for循环和while循环先判断条件是否成立,然后决定是否执行循环体(先判断后执行)
do…while循环先执行一次循环体,然后判断条件是否成立,是否继续执行循环体(先执行后判断)

for和while的区别:

条件控制语句所控制的自增变量,因为默认情况下归属for循环的语法结构中(也可以设置在循环外,那么该变量就能能够在循环结束后,可以被访问),在for循环结束后,就不能再次被访问到了

条件控制语句所控制的自增变量,对于while循环来说不归属其语法结构
中,在while循环结束后,该变量还可以继续使用

3.4 三种循环使用场景
  • 明确循环次数,推荐使用for
  • 不明确循环次数,推荐使用while
  • do…while 很少使用
3.5 循环嵌套

​ 在一个循环中,是可以嵌套另一个循环的。(任意形式循环可以嵌套任意形式循环)

比如,嵌套for循环:

for(int i = 1; i <= 5; i++){
    for(int j = 0; j < i; j++){
        System.out.print("*");
    }
    System.out.println();
}
(4)break

​ 循环语句中遇到break关键字,循环直接结束。

int i = 0; 
for(i = 1;i <= 10; i++){
    if(i == 4 || i == 8)
        break;
}
System.out.println("i = "+i); // i = 4

break不仅仅可以使用在循环中,只是一般用法是用在循环中,break是个关键字,它还可以用在switch中。

continue的用法和break基本一致,不过continue不能再switch中使用。

(5)continue

​ 循环语句中遇到continue关键字,本次循环结束,进入到下一次循环。

for(int i = 1;i <= 10; i++){
    if(i == 4 || i == 8){
    continue;
}
System.out.println("i = "+i); // i = 10
(6)label

​ 代码中出现多层循环嵌套,label标签可以使得程序员能一下子跳出内部循环。

​ 该标签可以使用在Java程序中的任意位置,意思就是起别名的的意思,一般使用在循环中,结合break才能起到实际意义,所以在其他地方使用Java程序会报警告。

label1: for(int i = 0; i < 3; i++) {//外层循环
	label2: for(int j = 0; j < 5; j++) {//内层循环
        if(j == 2) {
            //此时可直接跳出外层循环,然后往下执行
            break label1;
            }
        System.out.println("i = " + i + ", j = " + j);
        }
        System.out.println("----------------------");
  }

7、作用域

​ 作用域无论是否是Java程序还是其他语言都是很重要的,这是属于写程序的一种意识,作用域决定变量的使用范围,和该作用域内写什么程序,超出范围便找不到该变量。Java中作用域一个简单判断方法就是“ { } “ ,一个”{}“ 就是一个作用域,外层的 {} 的变量可以在内层中使用,内层中的 {} 不能再外层中使用(注意,内外层 {} 的同名变量 的使用采用就近原则。就近原则在Java中非常适用,但凡不确定使用哪个同名变量采用就近原则去判断就能欧够确定该处使用的是哪一个);变量的的作用域就是该变量最靠近的上一个 ”{“ 的范围。

8、方法和函数

​ Java中方法和函数是有区别,一般来说我们都会将函数近似看做方法,也就是将函数叫为方法。函数是结构化的思想,结构化编程,而Java是面向对象,需要对程序进行封装和复用,方法是面向对象,为了实现程序复用,一般而言,Java中我们都称为方法,不过需要了解这区别,有助于后面的一些程序设计上的学习,比如面向函数式编程。

​ 方法(method):就是完成特定功能的代码块!通过方法的定义和调用,可大大提高代码的复用性与可读性!

8.1 定义格式
修饰符 返回值类型 方法名(形式参数列表) {
	方法体语句;
}

修饰符:(final、static 视需求添加)

public

protected

默认(不加修饰符)

priavte

返回值类型:

基本数据类型(Java中八种)

引用数据类型(String、数组、集合、类,等)

void (不需要返回值类型)

方法名:自己定义的名字,命名方式一般采用小驼峰

形参列表:就是参数的声明,只是该参数的作用域是该方法中,且一般只是声明,在调用时,传过来的实参进行赋值。

注意事项:

带参方法定义时,参数中的数据类型与变量名都不能缺少,缺少任意一个程序将报错

带参方法定义时,多个参数之间使用逗号(,)分隔

8.2 方法调用

​ 方法分为静态方法和实例方法(区分:是否加有修饰符static)静态可由类名直接调用,实例就需要对象去调用,这是用类加载时存放的位置决定。

同类中方法调用格式: 方法名(实际参数列表);

同类中main方法中静态方法调用格式: 方法名(实际参数列表);

不同类中中静态方法调用格式: 类名.方法名(实际参数列表);

main方法中实例方法调用格式:对象名.方法名(实际参数列表); (先声明对象,不论是否在同一类中)

注意事项:

方法必须先定义,再调用

实际参数列表可以是常量,也可以是变量,也可以是表达式

实际参数类型要匹配形式参数类型(要么完全相同,要么能自动隐式类型转换

main方法是入口方法,一个程序中唯一,其可以调用其他普通方法其他方法不能调用main方法,普通方法可以相互调用。(换言之:main方法不能被自定义程序去调用,只能JVM去调用)

8.3方法重载

​ Java中的一个特性。
​ 指同一个类中定义的多个方法之间的关系,如果多个方法要构成重载,则需要同时满足下列条件:

多个方法在同一个类

多个方法具有相同的方法名

多个方法的参数列表不相同(参数类型不同或者数量不同)

重载跟函数的返回值类型无关

[ 两同:类同,方法名相同;一不同:参数列表不同;一无关:与返回值无关]

8.4方法重写

​ 首先作用范围不同,重载针对一个类,重写是针对于继承的,也就是连个类,重写是在子类中重新写父类的同名方法。形式上,重载和重写的方法名字和参数列表相同,但是重写的方法的修饰符可以不同,返回值类型也可以不同,另外一般重写的方法会加注释。@Override进行重写检查。

一般Java试题中会对重载和重写进行考察,两者就不是描述同一个东西,但是对于初学者来说,很容易混淆。所以此处我才放在一起,后面在继承处,会详写。

protected

默认(不加修饰符)

priavte

返回值类型:

基本数据类型(Java中八种)

引用数据类型(String、数组、集合、类,等)

void (不需要返回值类型)

方法名:自己定义的名字,命名方式一般采用小驼峰

形参列表:就是参数的声明,只是该参数的作用域是该方法中,且一般只是声明,在调用时,传过来的实参进行赋值。

注意事项:

带参方法定义时,参数中的数据类型与变量名都不能缺少,缺少任意一个程序将报错

带参方法定义时,多个参数之间使用逗号(,)分隔

8.2 方法调用

​ 方法分为静态方法和实例方法(区分:是否加有修饰符static)静态可由类名直接调用,实例就需要对象去调用,这是用类加载时存放的位置决定。

同类中方法调用格式: 方法名(实际参数列表);

同类中main方法中静态方法调用格式: 方法名(实际参数列表);

不同类中中静态方法调用格式: 类名.方法名(实际参数列表);

main方法中实例方法调用格式:对象名.方法名(实际参数列表); (先声明对象,不论是否在同一类中)

注意事项:

方法必须先定义,再调用

实际参数列表可以是常量,也可以是变量,也可以是表达式

实际参数类型要匹配形式参数类型(要么完全相同,要么能自动隐式类型转换

main方法是入口方法,一个程序中唯一,其可以调用其他普通方法其他方法不能调用main方法,普通方法可以相互调用。(换言之:main方法不能被自定义程序去调用,只能JVM去调用)

8.3方法重载

​ Java中的一个特性。
​ 指同一个类中定义的多个方法之间的关系,如果多个方法要构成重载,则需要同时满足下列条件:

多个方法在同一个类

多个方法具有相同的方法名

多个方法的参数列表不相同(参数类型不同或者数量不同)

重载跟函数的返回值类型无关

[ 两同:类同,方法名相同;一不同:参数列表不同;一无关:与返回值无关]

8.4方法重写

​ 首先作用范围不同,重载针对一个类,重写是针对于继承的,也就是连个类,重写是在子类中重新写父类的同名方法。形式上,重载和重写的方法名字和参数列表相同,但是重写的方法的修饰符可以不同,返回值类型也可以不同,另外一般重写的方法会加注释。@Override进行重写检查。

一般Java试题中会对重载和重写进行考察,两者就不是描述同一个东西,但是对于初学者来说,很容易混淆。所以此处我才放在一起,后面在继承处,会详写。

你可能感兴趣的:(Java,java,学习,笔记)